File: qapplication.rst

package info (click to toggle)
pytest-qt 4.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 644 kB
  • sloc: python: 4,144; makefile: 139
file content (90 lines) | stat: -rw-r--r-- 2,665 bytes parent folder | download
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