如何通过QTest访问QMessageBox

时间:2016-07-26 17:55:28

标签: qt qwidget qmessagebox qtestlib

我正在使用 QTest 在我的应用程序中创建一些自动 GUI测试

我可以使用以下命令从我的应用程序访问小部件:

savePushButton = mainWindow->findChild<QPushButton *>("savePushButton");

工作正常,但现在我必须点击 QMessageBox 的确定按钮。

我在我的应用程序中创建了 QMessageBox ,如下所示:

if( something_wrong )
{
    QMessageBox::warning(new Widget(), "Title", "Something wrong!");
}

如何访问此 QMessageBox 及其按钮?

2 个答案:

答案 0 :(得分:4)

我在以下链接中找到了解决方案:http://www.qtcentre.org/threads/31239-Testing-modal-dialogs-with-QTestLib

它使用命令QApplication::topLevelWidgets();来获取小部件列表。然后它搜索消息框小部件并模拟一个键输入(QTest::keyClick(mb, Qt::Key_Enter);),它将关闭消息框。

示例:

void MyTest::testDialog()
{
    QTimer::singleShot(500, this, SLOT(timeOut()));
    QVERIFY(functionThatProducesMessageBox());
}

void MyTest::timeOut()
{
    QWidgetList allToplevelWidgets = QApplication::topLevelWidgets();
    foreach (QWidget *w, allToplevelWidgets) {
        if (w->inherits("QMessageBox")) {
            QMessageBox *mb = qobject_cast<QMessageBox *>(w);
            QTest::keyClick(mb, Qt::Key_Enter);
        }
    }
}

头文件必须包含 Q_OBJECT 宏才能使用信号和插槽机制。 例如:

class MyClass: public QWidget
{
    Q_OBJECT
public:
    ...

它很适合我,因为当消息框出现时,UI(线程)被阻止。

注意:请记住在添加 Q_OBJECT 宏时重建项目。

答案 1 :(得分:3)

查看Qt's auto tests通常会有所帮助:

void ExecCloseHelper::timerEvent(QTimerEvent *te)
{
    if (te->timerId() != m_timerId)
        return;

    QWidget *modalWidget = QApplication::activeModalWidget();

    if (!m_testCandidate && modalWidget)
        m_testCandidate = modalWidget;

    if (m_testCandidate && m_testCandidate == modalWidget) {
        if (m_key == CloseWindow) {
            m_testCandidate->close();
        } else {
            QKeyEvent *ke = new QKeyEvent(QEvent::KeyPress, m_key, Qt::NoModifier);
            QCoreApplication::postEvent(m_testCandidate, ke);
        }
        m_testCandidate = Q_NULLPTR;
        killTimer(m_timerId);
        m_timerId = m_key = 0;
    }
}

根据该代码判断,您可以通过QApplication::activeModalWidget()获取消息框。测试本机(我假设它们是原生的)小部件是困难的,这可能是他们选择发送关键事件的原因,因为您不需要知道例如这些按钮的位置,就像点击鼠标一样。