pytest-qt
pytest-qt copied to clipboard
Help with "Okaying" a message box using pytest-qt.
Hello - I'd like to ask a question if you don't mind. Given a simple message box application such as :
from PyQt5.QtWidgets import QMessageBox, QWidget
def messageBoxFactory(parent : QWidget, title:str, msg:str, level="info"):
"""Display a popup of type `level` containing msg[0] (title) and msg[1] the message.
Makes use of the full QMessageBox (rather than QMessageBox.warning, for example) because
it is necessary to have a handle to the box later for testing.
"""
box = None
if level == "info":
box = QMessageBox(QMessageBox.Information, title, msg, QMessageBox.Ok, parent)
elif level == "warning":
box = QMessageBox(QMessageBox.Warning, title, msg, QMessageBox.Ok, parent)
elif level == "critical":
box = QMessageBox(QMessageBox.Critical, title, msg, QMessageBox.Ok, parent)
if not box:
raise ValueError("no QMessageBox created")
box.exec()
return box
how would one go about using pytest-qt's qbot to okay the popup? Here's my best try so far which does not work since the QMessageBox
exec
loop is running before qtbot
can try to press anything.
from PyQt5.QtWidgets import QMainWindow, QDialogButtonBox
from PyQt5.QtCore import Qt
import pytest
from pytestqt.qtbot import QtBot
from accos.view.MessageBoxFactory import messageBoxFactory
def test_mbf(qtbot: QtBot):
main_window = QMainWindow()
box = messageBoxFactory(main_window, "Informational Message", "Some information", level="info")
dialogButtonBox : QDialogButtonBox = box.children()[2]
okayBtn = dialogButtonBox.buttons()[0]
qtbot.mouseClick(okayBtn, Qt.LeftButton, Qt.NoModifier)
Thanks Ciaran
Hey,
Modal dialogs are often a pain to test, I suggest to mock (using monkeypatch
or pytest-mock
) the exec()
function. This way the message box won't even popup, and you can check in your test that exec
has been called, something like:
def test_mbf(qtbot: QtBot, mocker):
main_window = QMainWindow()
exec_mock = mocker.patch.object(QMessageBox, "exec")
messageBoxFactory(main_window, "Informational Message", "Some information", level="info")
assert exec_mock.call_count == 1