1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
Testing QApplication
====================
If your tests need access to a full ``QApplication`` instance to e.g. test exit
behavior or custom application classes, you can use the techniques described below:
Testing QApplication.exit()
--------------------------------
Some ``pytest-qt`` features, most notably ``waitSignal`` and ``waitSignals``,
depend on the Qt event loop being active. Calling ``QApplication.exit()``
from a test will cause the main event loop and auxiliary event loops to
exit and all subsequent event loops to fail to start. This is a problem if some
of your tests call an application functionality that calls
``QApplication.exit()``.
One solution is to *monkeypatch* ``QApplication.exit()`` in such tests to ensure
it was called by the application code but without effectively calling it.
For example:
.. code-block:: python
def test_exit_button(qtbot, monkeypatch):
exit_calls = []
monkeypatch.setattr(QApplication, "exit", lambda: exit_calls.append(1))
button = get_app_exit_button()
button.click()
assert exit_calls == [1]
Or using the ``mock`` package:
.. code-block:: python
def test_exit_button(qtbot):
with mock.patch.object(QApplication, "exit"):
button = get_app_exit_button()
button.click()
assert QApplication.exit.call_count == 1
Testing Custom QApplications
----------------------------
It's possible to test custom ``QApplication`` classes, but you need to be
careful to avoid multiple app instances in the same test. Assuming one defines a
custom application like below:
.. code-block:: python
from pytestqt.qt_compat import qt_api
class CustomQApplication(qt_api.QtWidgets.QApplication):
def __init__(self, *argv):
super().__init__(*argv)
self.custom_attr = "xxx"
def custom_function(self):
pass
If your tests require access to app-level functions, like
``CustomQApplication.custom_function()``, you can override the built-in
``qapp_cls`` fixture in your ``conftest.py`` to return your custom class:
.. code-block:: python
@pytest.fixture(scope="session")
def qapp_cls():
return CustomQApplication
The ``qapp`` fixture will then use the returned class instead of the default
``QApplication`` from ``QtWidgets``.
.. _setting-qapp-name:
Setting a QApplication name
---------------------------
By default, pytest-qt sets the ``QApplication.applicationName()`` to
``pytest-qt-qapp``. To use a custom name, you can set the ``qt_qapp_name``
option in ``pytest.ini``:
.. code-block:: ini
[pytest]
qt_qapp_name = frobnicate-tests
|