How can I get access to a QMessageBox by QTest

一曲冷凌霜 提交于 2019-12-10 10:37:24

问题


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?


回答1:


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.




回答2:


It often helps to look to 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;
    }
}

Judging from that code, you can get the message box via QApplication::activeModalWidget(). Testing native (I'm assuming they're native) widgets is difficult, which is likely why they chose to send key events, as you don't need to know e.g. the location of the buttons for those, as you would with a mouse click.



来源:https://stackoverflow.com/questions/38596785/how-can-i-get-access-to-a-qmessagebox-by-qtest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!