我正在为QTest调查GUI testing。似乎QTest中没有机制来异步测试signal回调。我是否误解了如何使用QTest,或误解了QTest提供的预期功能?
例如,我正在尝试测试一个信号,该信号会在点击QMessageBox时启动模态QPushButton弹出窗口。我想在单击按钮和单击QMessageBox上的“确定”之间测试事件和状态。我尝试过使用QSignalSpy.wait()
,QTestEventList.simulate()
,QTest::mouseClick()
,QTest::mouseEvent()
和QTRY_VERIFY()
,从测试代码调用时,所有这些都不会返回在QMessageBox弹出窗口中单击“确定”后。因此,要在所有事件处理程序返回之前测试任何内容,我必须做一些事情,比如在被测对象上安装事件过滤器,并编写我自己的异步测试代码。
如果我们没有使用测试库,这就是我们必须编写的相同代码,我们可以在不使用QTest的情况下完成所有这些操作。例如,我们可以手动get a handle到被测对象,connect signals进行测试,invoke an event来触发事件处理程序或invoke the signal manually,还可以编写已安装的测试处理程序在将执行返回到启动事件的位置之前与测试环境交互。 QTest在这里获得了什么?
(也发布在Qt forums)
答案 0 :(得分:1)
使用qtestlib
处理同步事件有点棘手。如果您查看qtestlib
的来源,您会发现事件模拟非常简单。因此,qtestlib
没有提供处理同步事件的任何方法。无论如何,它可以处理由您的应用程序生成的Qt模态窗口。
这个问题的主要注意事项是除了GUI线程之外,不能从其他线程访问GUI对象。此外,GUI只能在创建QApplication
的线程中创建。因此,在QMessageBox
中生成一个新线程以按下“确定”按钮的一些技巧将会失败,例如this object can not be accessed from other thread
QWidget
来源中的class Helper {
Helper() {}
public slots:
doSmth();
}
错误。
为避免这种情况,可以使用Qt插槽机制触发异步事件。首先,您应该使用某个插槽定义Helper对象,例如
void BlahblahTest::testCase1() {
Helper h;
...
此外,您应该在测试用例中创建此对象的实例
QTest::mouseClick
在您使用QTimer::singleShot(delay, &h, SLOT(doSmth));
调用某个同步事件之前,请使用
doSmth
取决于您的需求,void Helper::doSmth() {
QList<QWidget *> tlw = qApp()->topLevelWidgets();
foreach (QWidget *w, tlw) {
if (...) { // w is a messagebox
Qt::keyClick(w, Qt::Key_Enter);
}
}
}
的实施可能就像那样
{{1}}