Search code examples
qtqwidgetqmessageboxqtestlib

How can I get access to a QMessageBox by QTest


I am creating some automated GUI tests in my application using QTest.

I can access the widgets from my application using the command:

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

It is working fine, but now I have to click on the OK button of a QMessageBox.

I created the QMessageBox in my application like this:

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

How can I have access to this QMessageBox, and its buttons?


Solution

  • I found a solution on the following link: http://www.qtcentre.org/threads/31239-Testing-modal-dialogs-with-QTestLib .

    It uses the command QApplication::topLevelWidgets(); to get a widget list. Then it searches for the message box widget and simulates a key enter (QTest::keyClick(mb, Qt::Key_Enter);) which closes the message box.

    Example:

    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);
            }
        }
    }
    

    The header file must contain the Q_OBJECT macro to use the signals and slots mechanism. Example:

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

    It worked well for me since the UI (thread) is blocked when the message box appears.

    Note: remember to rebuild the project when you add the Q_OBJECT macro.