0

我正在调查QTest以进行GUI 测试。QTest 中似乎没有异步测试信号回调的机制。我是否误解了如何使用 QTest,或者误解了 QTest 提供的预期功能?

例如,我正在尝试测试一个信号,该信号会启动一个模态QMessageBox弹出窗口以响应单击QPushButton。我想测试单击按钮和单击 QMessageBox 上的“确定”之间的事件和状态。我已经尝试使用QSignalSpy.wait(), QTestEventList.simulate(), QTest::mouseClick(),QTest::mouseEvent()QTRY_VERIFY(),所有这些在从测试代码中调用时,直到单击 QMessageBox 弹出窗口上的“确定”后才返回。因此,要在所有事件处理程序返回之前测试任何内容,我必须在被测对象上安装一个事件过滤器,并编写我自己的异步测试代码。

如果我们不使用测试库,这与我们必须编写的所有代码相同,并且我们可以在不使用 QTest 的情况下完成所有这些工作。例如,我们可以手动获取被测对象的句柄,连接信号进行测试,调用事件触发事件处理程序或手动调用信号,也可以在返回执行之前编写与测试环境交互的已安装测试处理程序到事件启动的时间点。QTest 在这里为我们带来了什么?

(也发布在Qt 论坛上

4

1 回答 1

1

使用同步事件处理qtestlib有点棘手。如果您查看 的来源qtestlib,您会发现事件模拟非常简单。因此,qtestlib不提供任何方法来处理同步事件。无论如何,可以处理由您的应用程序生成的 Qt 模态窗口。

这个问题的主要注意事项是 GUI 对象不能从除 GUI 线程之外的其他线程访问。而且 GUI 只能在创建的线程中QApplication创建。因此,诸如生成新线程以按下 OK 按钮之类的技巧QMessageBox将不会成功,并且会出现错误,例如源中this object can not be accessed from other thread的某处QWidget

为了避免这种情况,可以使用 Qt 插槽机制触发异步事件。首先,您应该定义一个带有某个插槽的 Helper 对象,例如

class Helper {
    Helper() {}
    public slots:
        doSmth();
}

此外,您应该在测试用例中创建此对象的实例

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);
        }
    }
}
于 2014-04-27T20:55:38.637 回答