保持对话框不显示PySide进行测试

时间:2014-10-20 16:21:11

标签: python qt unit-testing pyqt pyside

我正在为我制作的表单编写一些测试函数。有几个QMessageBox被调用(一个通过QMessageBox.question方法,一个通过QMessageBox.information方法。虽然我的自定义小部件没有显示在屏幕上,但这两个实际上显示在屏幕上。

我尝试通过循环访问我在QApplication.topLevelWidgets()中获取的小部件并解雇正确的小部件来解雇它们,但是,似乎我的代码仅在我手动关闭MessageBox后继续执行。

所以我的问题是双重的:

1)如何在测试期间保持QMessageBox(或任何小部件真的)不在屏幕上显示。

2)我如何以编程方式接受/拒绝/关闭此小部件。

3 个答案:

答案 0 :(得分:1)

您可以设置计时器以自动接受对话框。如果超时很长,对话框仍会显示一段时间:

w = QtGui.QDialog(None)
t = QtCore.QTimer(None)
t.timeout.connect(w.accept)
t.start(1)
w.exec_()

对于您的具体情况,如果您不想触摸作为睾丸的代码,您可以让计时器运行一个函数来接受所有当前的模态小部件,如您所建议的那样:

def accept_all():
    for wid in app.topLevelWidgets():
        if wid.__class__ == QtGui.QDialog:   #or QMessageBox, etc:
            wid.accept()

t = QtCore.QTimer(None)
t.timeout.connect(accept_all)
t.start(10)

答案 1 :(得分:0)

我决定使用mock模块。这似乎更好,因为其他解决方案实际上会在屏幕上绘制,这对于测试来说并不是最佳的。

如果您遇到同样的问题并且想要模拟问题QMessageBox,您可以这样:

@patch.object(path.QMessageBox, "question", return_value=QtGui.QMessageBox.Yes)

将模拟单击Yes按钮的MessageBox。

答案 2 :(得分:0)

我认为使用Qt测试(包括PySide / PyQt)模拟GUI交互并根据需要单独进行专门的GUI测试是有道理的。

对于模拟GUI交互,我使用mock库,就像我自己经常做的那样。这样做的缺点是您必须依赖于模拟定义,这些定义可能与您的生产应用程序不同步。另一方面,您的测试将比涉及实际的GUI更快。

为了测试GUI本身,我使用GUI测试工具(例如Froglogic Squish)编写单独的测试层。它通常会导致更多涉及/更慢的测试,但您将直接测试您的应用程序,而不仅仅是模拟GUI层。在这方面,我的方法是在预算允许的情况下投资这样的工具,并在必要时运行这些测试,记住它们会相对较慢。