我正在为我制作的表单编写一些测试函数。有几个QMessageBox被调用(一个通过QMessageBox.question方法,一个通过QMessageBox.information方法。虽然我的自定义小部件没有显示在屏幕上,但这两个实际上显示在屏幕上。
我尝试通过循环访问我在QApplication.topLevelWidgets()中获取的小部件并解雇正确的小部件来解雇它们,但是,似乎我的代码仅在我手动关闭MessageBox后继续执行。
所以我的问题是双重的:
1)如何在测试期间保持QMessageBox(或任何小部件真的)不在屏幕上显示。
2)我如何以编程方式接受/拒绝/关闭此小部件。
答案 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层。在这方面,我的方法是在预算允许的情况下投资这样的工具,并在必要时运行这些测试,记住它们会相对较慢。