Функциональный тест для QMessageBox... почему не работает?
Я бы разработал несколько функциональных тестов для приложения pyqt, которое использует PyQt (или PySide) в качестве библиотеки GUI. В тестах используются библиотеки Unittest и Qttest, о которых сообщалось во многих ресурсах, например, этот вопрос о стековом потоке: модульное и функциональное тестирование приложения на основе PySide? Для главного окна все работает нормально, и код прекрасно имитирует типы клавиатуры и щелчки и движения мыши, но "дьявол кроется в деталях"... и этот метод не работает для QMessageBox.
В классе главного окна, для управления IOError
при открытии файла я инициализирую QMessageBox:
self.IOErrMsgBox = QtGui.QMessageBox()
self.IOErrMsgBox.setText("<b>Error</b>")
self.IOErrMsgBox.setInformativeText("""
<p>There was an error opening
the project file:
%s.</p>"""%(path,))
self.IOErrMsgBox.setStandardButtons(QtGui.QMessageBox.Ok)
self.IOErrMsgBox.setDefaultButton(QtGui.QMessageBox.Ok)
self.IOErrMsgBox.exec_()
Чтобы проверить, как это работает, в функциональном тесте у меня есть:
def test__open_project(self):
self.MainWin._project_open(wrong_path, flag='c')
# the function that handles the exception
# and initializes the QMessageBox.
IOErrMsgBox = self.MainWin.IOErrMsgBox
# Reference to the initialized QMessageBox.
self.assertIsInstance(IOErrMsgBox, QMessageBox)
okWidget = self.MainWin.IOErrMsgBox.button(IOErrMsgBox.Ok)
QTest.mouseClick(okWidget, Qt.LeftButton)
или, в качестве альтернативы:
def test__open_project(self):
#... some code, exactly like previous example except for last row...
QTest.keyClick(okWidget, 'o', Qt.AltModifier)
но никто не работает... и кнопка Ok не нажата, и я могу сделать это с помощью моего указателя мыши:(
Какие-либо предложения?
1 ответ
Вопрос в общем о том, как тестировать модальные диалоги.
Любой модальный диалог, включая QMessageBox, не вернется из exec_()
пока он не будет закрыт, поэтому тестовый код в вашем втором блоке кода, вероятно, никогда не будет выполнен.
Вы могли бы просто show()
это (делает его немодальным), а затем следуйте вашему коду, но не забудьте закрыть и удалить диалоговое окно впоследствии.
Или вы используете Timer и планируете щелкнуть по кнопке OK (аналогично диалоговому окну Test modeal с Qt Test). Вот пример:
from PySide import QtGui, QtCore
app = QtGui.QApplication([])
box = QtGui.QMessageBox()
box.setStandardButtons(QtGui.QMessageBox.Ok)
button = box.button(QtGui.QMessageBox.Ok)
QtCore.QTimer.singleShot(0, button.clicked)
box.exec_()