QMessageBox的功能测试...为什么不工作?

2 投票
1 回答
2185 浏览
提问于 2025-04-18 10:52

我想为一个使用PyQt(或PySide)作为图形界面的应用程序开发一些功能测试。这些测试使用Unittest和Qttest库,很多资源都有提到,比如这个StackOverflow的问题:如何对基于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 个回答

4

这个问题主要是关于如何测试模态对话框

任何模态对话框,比如QMessageBox,都不会在你关闭它之前从exec_()这个函数返回,所以你第二段代码里的测试代码可能根本不会被执行。

你可以选择直接用show()来显示它(这样就变成了非模态对话框),然后再继续你的代码,但记得最后要关闭并删除这个对话框。

或者你可以使用一个定时器,安排一个点击“确定”按钮的操作(类似于使用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_()

撰写回答