0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-13 11:11:49 +02:00

feat: added reference utils to compare renderings of widgets

This commit is contained in:
2024-07-06 20:25:09 +02:00
committed by wyzula_j
parent 1b017edfad
commit 2988fd387e
7 changed files with 96 additions and 66 deletions

View File

@ -145,7 +145,7 @@ tests:
coverage_format: cobertura
path: coverage.xml
paths:
- tests/unit_tests/reference_failures/
- tests/reference_failures/
when: always
test-matrix:

View File

@ -0,0 +1,92 @@
import os
import sys
from PIL import Image, ImageChops
from qtpy.QtGui import QPixmap
import bec_widgets
REFERENCE_DIR = os.path.join(
os.path.dirname(os.path.dirname(bec_widgets.__file__)), "tests/references"
)
REFERENCE_DIR_FAILURES = os.path.join(
os.path.dirname(os.path.dirname(bec_widgets.__file__)), "tests/reference_failures"
)
def compare_images(image1_path: str, reference_image_path: str):
"""
Load two images and compare them pixel by pixel
Args:
image1_path(str): The path to the first image
reference_image_path(str): The path to the reference image
Raises:
ValueError: If the images are different
"""
image1 = Image.open(image1_path)
image2 = Image.open(reference_image_path)
if image1.size != image2.size:
raise ValueError("Image size has changed")
diff = ImageChops.difference(image1, image2)
if diff.getbbox():
# copy image1 to the reference directory to upload as artifact
os.makedirs(REFERENCE_DIR_FAILURES, exist_ok=True)
image_name = os.path.join(REFERENCE_DIR_FAILURES, os.path.basename(image1_path))
image1.save(image_name)
print(f"Image saved to {image_name}")
raise ValueError("Images are different")
def snap_and_compare(widget: any, output_directory: str, suffix: str = ""):
"""
Save a rendering of a widget and compare it to a reference image
Args:
widget(any): The widget to render
output_directory(str): The directory to save the image to
suffix(str): A suffix to append to the image name
Raises:
ValueError: If the images are different
Examples:
snap_and_compare(widget, tmpdir, suffix="started")
"""
if not isinstance(output_directory, str):
output_directory = str(output_directory)
os_suffix = sys.platform
name = (
f"{widget.__class__.__name__}_{suffix}_{os_suffix}.png"
if suffix
else f"{widget.__class__.__name__}_{os_suffix}.png"
)
# Save the widget to a pixmap
test_image_path = os.path.join(output_directory, name)
pixmap = QPixmap(widget.size())
widget.render(pixmap)
pixmap.save(test_image_path)
try:
reference_path = os.path.join(REFERENCE_DIR, f"{widget.__class__.__name__}")
reference_image_path = os.path.join(reference_path, name)
if not os.path.exists(reference_image_path):
raise ValueError(f"Reference image not found: {reference_image_path}")
compare_images(test_image_path, reference_image_path)
except ValueError:
image = Image.open(test_image_path)
os.makedirs(REFERENCE_DIR_FAILURES, exist_ok=True)
image_name = os.path.join(REFERENCE_DIR_FAILURES, name)
image.save(image_name)
print(f"Image saved to {image_name}")
raise

View File

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,11 +1,7 @@
import os
import sys
import pytest
import qdarktheme
from PIL import Image, ImageChops
from qtpy.QtGui import QPixmap
from bec_widgets.utils.reference_utils import snap_and_compare
from bec_widgets.widgets.spinner.spinner import SpinnerWidget
@ -18,75 +14,17 @@ def spinner_widget(qtbot):
yield spinner
def save_pixmap(widget, filename):
pixmap = QPixmap(widget.size())
widget.render(pixmap)
pixmap.save(str(filename))
return pixmap
def compare_images(image1_path: str, reference_image_path: str):
image1 = Image.open(image1_path)
image2 = Image.open(reference_image_path)
if image1.size != image2.size:
raise ValueError("Image size has changed")
diff = ImageChops.difference(image1, image2)
if diff.getbbox():
# copy image1 to the reference directory to upload as artifact
output_dir = os.path.join(os.path.dirname(__file__), "reference_failures")
os.makedirs(output_dir, exist_ok=True)
image_name = os.path.join(output_dir, os.path.basename(image1_path))
image1.save(image_name)
print(f"Image saved to {image_name}")
raise ValueError("Images are different")
def test_spinner_widget_paint_event(spinner_widget, qtbot):
spinner_widget.paintEvent(None)
def snap_and_compare(widget, tmpdir, suffix=""):
os_suffix = sys.platform
name = (
f"{widget.__class__.__name__}_{suffix}_{os_suffix}.png"
if suffix
else f"{widget.__class__.__name__}_{os_suffix}.png"
)
# Save the widget to a pixmap
test_image_path = str(tmpdir / name)
pixmap = QPixmap(widget.size())
widget.render(pixmap)
pixmap.save(test_image_path)
try:
references_path = os.path.join(os.path.dirname(__file__), "references")
reference_image_path = os.path.join(references_path, name)
if not os.path.exists(reference_image_path):
raise ValueError(f"Reference image not found: {reference_image_path}")
compare_images(test_image_path, reference_image_path)
except ValueError:
image = Image.open(test_image_path)
output_dir = os.path.join(os.path.dirname(__file__), "reference_failures")
os.makedirs(output_dir, exist_ok=True)
image_name = os.path.join(output_dir, name)
image.save(image_name)
print(f"Image saved to {image_name}")
raise
def test_spinner_widget_rendered(spinner_widget, qtbot, tmpdir):
spinner_widget.update()
qtbot.wait(200)
snap_and_compare(spinner_widget, tmpdir, suffix="")
snap_and_compare(spinner_widget, str(tmpdir), suffix="")
spinner_widget._started = True
spinner_widget.update()
qtbot.wait(200)
snap_and_compare(spinner_widget, tmpdir, suffix="started")
snap_and_compare(spinner_widget, str(tmpdir), suffix="started")