From 34fc057cfd6695c015bb3996e8177b2e25488dd4 Mon Sep 17 00:00:00 2001 From: wakonig_k Date: Fri, 25 Apr 2025 11:34:35 +0200 Subject: [PATCH] test: add tests for omny alignment gui --- .../widgets/omny_alignment/omny_alignment.py | 2 +- pyproject.toml | 4 + tests/tests_bec_widgets/conftest.py | 83 +++++++++++++++++++ .../tests_bec_widgets/test_omny_alignment.py | 35 ++++++++ 4 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 tests/tests_bec_widgets/conftest.py create mode 100644 tests/tests_bec_widgets/test_omny_alignment.py diff --git a/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.py b/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.py index 7573b3d..66f8418 100644 --- a/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.py +++ b/csaxs_bec/bec_widgets/widgets/omny_alignment/omny_alignment.py @@ -12,7 +12,7 @@ from qtpy.QtWidgets import QVBoxLayout, QWidget logger = bec_logger.logger -if TYPE_CHECKING: +if TYPE_CHECKING: # pragma: no cover from bec_widgets.widgets.plots.image.image import Image from bec_widgets.widgets.utility.toggle.toggle import ToggleSwitch from qtpy.QtWidgets import QLineEdit, QPushButton diff --git a/pyproject.toml b/pyproject.toml index 8ddb4b0..f614b32 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ dev = [ "pytest", "pytest-random-order", "pytest-redis", + "pytest-qt", ] [project.entry-points."bec"] @@ -55,6 +56,9 @@ plugin_ipython_client_post = "csaxs_bec.bec_ipython_client.startup" [project.entry-points."bec.widgets.user_widgets"] plugin_widgets = "csaxs_bec.bec_widgets.widgets" +[project.entry-points."bec.widgets.auto_updates"] +plugin_widgets_update = "csaxs_bec.bec_widgets.auto_updates" + [tool.hatch.build.targets.wheel] include = ["*"] diff --git a/tests/tests_bec_widgets/conftest.py b/tests/tests_bec_widgets/conftest.py new file mode 100644 index 0000000..fd561bd --- /dev/null +++ b/tests/tests_bec_widgets/conftest.py @@ -0,0 +1,83 @@ +from unittest import mock + +import pytest +from bec_widgets.cli.rpc.rpc_register import RPCRegister +from bec_widgets.utils import bec_dispatcher as bec_dispatcher_module +from bec_widgets.utils import error_popups +from pytestqt.exceptions import TimeoutError as QtBotTimeoutError +from qtpy.QtWidgets import QApplication + + +@pytest.hookimpl(tryfirst=True, hookwrapper=True) +def pytest_runtest_makereport(item, call): + # execute all other hooks to obtain the report object + outcome = yield + rep = outcome.get_result() + + item.stash["failed"] = rep.failed + + +@pytest.fixture(autouse=True) +def qapplication(qtbot, request): # pylint: disable=unused-argument + yield + + # if the test failed, we don't want to check for open widgets as + # it simply pollutes the output + if request.node.stash._storage.get("failed"): + print("Test failed, skipping cleanup checks") + return + bec_dispatcher = bec_dispatcher_module.BECDispatcher() + bec_dispatcher.stop_cli_server() + + qapp = QApplication.instance() + qapp.processEvents() + if hasattr(qapp, "os_listener") and qapp.os_listener: + qapp.removeEventFilter(qapp.os_listener) + try: + qtbot.waitUntil(lambda: qapp.topLevelWidgets() == []) + except QtBotTimeoutError as exc: + raise TimeoutError(f"Failed to close all widgets: {qapp.topLevelWidgets()}") from exc + + +@pytest.fixture(autouse=True) +def rpc_register(): + yield RPCRegister() + RPCRegister.reset_singleton() + + +@pytest.fixture(autouse=True) +def bec_dispatcher(threads_check): # pylint: disable=unused-argument + bec_dispatcher = bec_dispatcher_module.BECDispatcher() + yield bec_dispatcher + bec_dispatcher.disconnect_all() + # clean BEC client + bec_dispatcher.client.shutdown() + # stop the cli server + bec_dispatcher.stop_cli_server() + # reinitialize singleton for next test + bec_dispatcher_module.BECDispatcher.reset_singleton() + + +@pytest.fixture(autouse=True) +def clean_singleton(): + error_popups._popup_utility_instance = None + + +def create_widget(qtbot, widget, *args, **kwargs): + """ + Create a widget and add it to the qtbot for testing. This is a helper function that + should be used in all tests that require a widget to be created. + + Args: + qtbot (fixture): pytest-qt fixture + widget (QWidget): widget class to be created + *args: positional arguments for the widget + **kwargs: keyword arguments for the widget + + Returns: + QWidget: the created widget + """ + widget = widget(*args, **kwargs) + qtbot.addWidget(widget) + qtbot.waitExposed(widget) + return widget diff --git a/tests/tests_bec_widgets/test_omny_alignment.py b/tests/tests_bec_widgets/test_omny_alignment.py new file mode 100644 index 0000000..407a8fe --- /dev/null +++ b/tests/tests_bec_widgets/test_omny_alignment.py @@ -0,0 +1,35 @@ +import pytest + +from csaxs_bec.bec_widgets.widgets.omny_alignment.omny_alignment import OmnyAlignment + + +@pytest.fixture +def omny_alignment(qtbot): + widget = OmnyAlignment() + qtbot.addWidget(widget) + qtbot.waitExposed(widget) + return widget + + +def test_omny_alignment_set_user_message(omny_alignment): + """ + Test the set_user_message method of the OmnyAlignment widget. + """ + # Set a message + message = "Test message" + omny_alignment.user_message = message + + # Check if the message is set correctly + assert omny_alignment.components["messageLineEdit"].text() == message + + +def test_omny_alignment_set_sample_name(omny_alignment): + """ + Test the set_sample_name method of the OmnyAlignment widget. + """ + # Set a sample name + sample_name = "Test sample" + omny_alignment.sample_name = sample_name + + # Check if the sample name is set correctly + assert omny_alignment.components["sampleLineEdit"].text() == sample_name