Skip to content

Commit

Permalink
component library tests
Browse files Browse the repository at this point in the history
  • Loading branch information
l0uden committed Nov 13, 2024
1 parent 285f566 commit ea31d69
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 0 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/test-component-library-vizro-core.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Integration tests Component Library

defaults:
run:
working-directory: vizro-core

on:
push:
branches: [main]
pull_request:
branches:
- main

env:
PYTHONUNBUFFERED: 1
FORCE_COLOR: 1

jobs:
test-component-library-vizro-core:
name: test-component-library-vizro-core

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: 3.12

- name: Install Hatch
run: pip install hatch

- name: Show dependency tree
run: hatch run tests:pip tree

- name: Run integration tests
run: hatch run tests:test-component-library
9 changes: 9 additions & 0 deletions vizro-core/hatch.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ schema-check = ["python schemas/generate.py --check"]
# See comments added in https://github.com/mckinsey/vizro/pull/444.
test = "pytest tests --headless {args}"
test-integration = "pytest tests/integration --headless {args}"
test-component-library = "pytest tests/component_library --headless {args}"
test-js = "./tools/run_jest.sh {args}"
test-unit = "pytest tests/unit {args}"
test-unit-coverage = [
Expand Down Expand Up @@ -118,6 +119,14 @@ extra-dependencies = [
features = ["kedro"]
python = "3.9"

[envs.tests]
extra-dependencies = [
"imutils",
"opencv-python",
"pyhamcrest"
]
python = "3.12"

[publish.index]
disable = true

Expand Down
Empty file added vizro-core/tests/__init__.py
Empty file.
93 changes: 93 additions & 0 deletions vizro-core/tests/component_library/test_component_library.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# ruff: noqa: F403, F405
import dash_bootstrap_components as dbc
import pandas as pd
import pytest
from dash import Dash, html
from vizro.figures.library import kpi_card, kpi_card_reference

from tests.helpers.common import compare_images

df_kpi = pd.DataFrame(
{
"Actual": [100, 200, 700],
"Reference": [100, 300, 500],
"Category": ["A", "B", "C"],
}
)

example_cards = [
kpi_card(data_frame=df_kpi, value_column="Actual", title="KPI with value"),
kpi_card(
data_frame=df_kpi,
value_column="Actual",
title="KPI with aggregation",
agg_func="median",
),
kpi_card(
data_frame=df_kpi,
value_column="Actual",
title="KPI formatted",
value_format="${value:.2f}",
),
kpi_card(
data_frame=df_kpi,
value_column="Actual",
title="KPI with icon",
icon="shopping_cart",
),
]

example_reference_cards = [
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI ref. (pos)",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
agg_func="median",
title="KPI ref. (neg)",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI ref. formatted",
value_format="{value}€",
reference_format="{delta}€ vs. last year ({reference}€)",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI ref. with icon",
icon="shopping_cart",
),
]


@pytest.mark.filterwarnings("ignore:HTTPResponse.getheader():DeprecationWarning")
@pytest.mark.filterwarnings("ignore::pytest.PytestUnhandledThreadExceptionWarning")
@pytest.mark.filterwarnings("ignore:unclosed file:ResourceWarning")
def test_kpi_card(dash_duo):
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dbc.Container(
[
html.H1(children="KPI Cards"),
dbc.Stack(
children=[
dbc.Row([dbc.Col(kpi_card) for kpi_card in example_cards]),
dbc.Row([dbc.Col(kpi_card) for kpi_card in example_reference_cards]),
],
gap=4,
),
]
)
dash_duo.start_server(app)
dash_duo.wait_for_page(timeout=20)
dash_duo.wait_for_element("div[class='card-kpi card']")
compare_images(dash_duo.driver, "base_kpi_comp_lib.png", "tests_kpi_comp_lib")
assert dash_duo.get_logs() == [], "browser console should contain no error"
Empty file.
50 changes: 50 additions & 0 deletions vizro-core/tests/helpers/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import subprocess

import cv2
import imutils
from hamcrest import assert_that, equal_to


def comparison_logic(original_image, new_image):
"""Comparison process."""
difference = cv2.subtract(original_image, new_image)
blue, green, red = cv2.split(difference)
assert_that(cv2.countNonZero(blue), equal_to(0), reason="Blue channel is different")
assert_that(
cv2.countNonZero(green), equal_to(0), reason="Green channel is different"
)
assert_that(cv2.countNonZero(red), equal_to(0), reason="Red channel is different")


def create_image_difference(original, new):
"""Creates new image with diff of images comparison."""
diff = original.copy()
cv2.absdiff(original, new, diff)
gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
for i in range(0, 3):
dilated = cv2.dilate(gray.copy(), None, iterations=i + 1)
(t_var, thresh) = cv2.threshold(dilated, 3, 255, cv2.THRESH_BINARY)
cnts = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
for contour in cnts:
(x, y, width, height) = cv2.boundingRect(contour)
cv2.rectangle(new, (x, y), (x + width, y + height), (0, 255, 0), 2)
return new


def compare_images(browserdriver, base_image, test_image_name):
"""Comparison logic and diff files creation."""
browserdriver.save_screenshot(f"{test_image_name}_branch.png")
original = cv2.imread(f"screenshots/{base_image}")
new = cv2.imread(f"{test_image_name}_branch.png")
try:
comparison_logic(original, new)
subprocess.call(f"rm -rf {test_image_name}_branch.png", shell=True)
except (AssertionError, AttributeError) as exp:
subprocess.call(f"cp {test_image_name}_branch.png {base_image}", shell=True)
diff = create_image_difference(original=new, new=original)
cv2.imwrite(f"{test_image_name}_diff_main.png", diff)
raise Exception("pictures are not the same") from exp
except cv2.error as exp:
subprocess.call(f"cp {test_image_name}_branch.png {base_image}", shell=True)
raise Exception("pictures has different sizes") from exp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ea31d69

Please sign in to comment.