I am using pytest-qt
and its waitSignal()
method to test a QDialog
but it is not working. Here is a minimal example (my real application is more complex):
import sys
from PyQt6.QtWidgets import (
QApplication, QDialog, QGridLayout, QPushButton
)
def get_dialog(app):
dialog = QDialog()
dialog.resize(300,200)
dialog.setWindowTitle("Test dialog")
layout = QGridLayout()
button1 = QPushButton("&Ok", dialog)
def ok_pressed():
dialog.done(0)
button1.clicked.connect(ok_pressed)
layout.addWidget(button1, 0, 0)
button2 = QPushButton("&Cancel", dialog)
def cancel_pressed():
dialog.done(1)
button2.clicked.connect(cancel_pressed)
layout.addWidget(button2, 0, 1)
dialog.setLayout(layout)
dialog.open()
return dialog, button1
def main():
app = QApplication(sys.argv)
get_dialog(app)
app.exec()
def test_dialog(qtbot, qapp):
app = qapp
dialog, button1 = get_dialog(app)
button1.click()
with qtbot.waitSignal(dialog.finished, timeout=2000):
pass
assert True
if __name__ == '__main__':
main()
Running this example with pytest gives:
$ pytest t.py
============================================================================ test session starts ============================================================================
platform linux -- Python 3.10.4, pytest-7.3.2, pluggy-1.0.0
PyQt6 6.5.1 -- Qt runtime 6.5.0 -- Qt compiled 6.5.1
rootdir: /home/hakon/test/python/pytest-qt/qdialog-cancel/pre
plugins: mock-3.11.1, qt-4.2.0, anyio-3.7.1
collected 1 item
t.py F [100%]
================================================================================= FAILURES ==================================================================================
________________________________________________________________________________ test_dialog ________________________________________________________________________________
qtbot = <pytestqt.qtbot.QtBot object at 0x7fea78d47a30>, qapp = <PyQt6.QtWidgets.QApplication object at 0x7fea78d5c1f0>
def test_dialog(qtbot, qapp):
app = qapp
dialog, button1 = get_dialog(app)
button1.click()
> with qtbot.waitSignal(dialog.finished, timeout=2000):
E pytestqt.exceptions.TimeoutError: Signal finished(int) not emitted after 2000 ms
t.py:36: TimeoutError
--------------------------------------------------------------------------- Captured Qt messages ----------------------------------------------------------------------------
QtWarningMsg: Could not connect "org.freedesktop.IBus" to globalEngineChanged(QString)
========================================================================== short test summary info ==========================================================================
FAILED t.py::test_dialog - pytestqt.exceptions.TimeoutError: Signal finished(int) not emitted after 2000 ms
============================================================================= 1 failed in 2.02s =============================================================================
so the signal dialog.finished
is not emitted or I am not using waitSignal()
correctly. However, if I use waitUntil()
instead of waitSignal()
it works fine:
def test_dialog(qtbot, qapp):
app = qapp
dialog, button1 = get_dialog(app)
dialog_done = False
def dialog_done_cb():
nonlocal dialog_done
dialog_done = True
dialog.finished.connect(dialog_done_cb)
button1.click()
qtbot.waitUntil(lambda: dialog_done)
assert True
Since this works, it also indicates that the dialog.finished
signal is emitted and I am not using waitSignal()
correctly. Any idea what might be the problem?
I am not using waitSignal() correctly.
It seems to work if I move button1.click()
inside the context manager:
def test_dialog(qtbot, qapp):
app = qapp
dialog, button1 = get_dialog(app)
with qtbot.waitSignal(dialog.finished, timeout=2000):
button1.click()
assert True
Maybe it did not work because the signal was emitted too early?