Qt Auto-UI测试由于消息框而停止.如何模拟在消息框上输入? [英] Qt Auto-UI Testing stopping because of messagebox. How to simulate enter on messagebox?

查看:181
本文介绍了Qt Auto-UI测试由于消息框而停止.如何模拟在消息框上输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的任务是为正在开发的软件编写自动化的UI测试.碰巧是这样,有一些单选按钮会触发一个消息框,该框会停止我的自动测试,直到我手动确认它(按ENTER键)为止.问题是我不知道如何调用该新召唤的消息框,然后由QTest::keyClick(<object>, QtKey::Key_Enter);确认该消息框,并让我的自动化测试继续运行.

My task is to write an automated UI test for a software being developed. It happens so, that there are radiobuttons triggering a messagebox, which stops my automated test until I manually confirm it (pressing ENTER). The issue is that I do not know how I can call that newly summoned messagebox and then have it confirmed by QTest::keyClick(<object>, QtKey::Key_Enter); and have my automated test continue the run.

我正在使用QWidgets,QApplication,Q_OBJECT和QtTest. 我将提供与我正在使用的代码类似的代码:

I am using QWidgets, QApplication, Q_OBJECT and QtTest. I will provide a code similar to what I am working with:

void testui1(){
Form1* myform = new Form1();
myform->show();
QTest::mouseClick(myform->radioButton01, Qt::LeftButton, Qt::NoModifier, QPoint(), 100);
// Message box pops up and stops the operation until confirmed
QTest::mouseClick(myform->radioButton02, Qt::LeftButton, Qt::NoModifier, QPoint(), 100);
// again
...
}

如何精确编写脚本以自动确认消息框?该消息框仅是[OK]类型,因此无论我是否按了Yes或No,都不需要它返回.QTest::keyClick(<target object>, Qt::Key_Enter)方法需要知道应按Enter到哪个对象.我尝试将myform包含到对象中,但它不起作用.谷歌搜索我没有找到答案.我发现以下结果无法满足我的需求

How exactly can I script to confirm the message box automatically? The message box is only an [OK] type, so I don't need it to return whether I have pressed Yes or No. A QTest::keyClick(<target object>, Qt::Key_Enter) method needs to know to which object it should press enter to. I tried including myform into the object and it did not work. Googling I did not find the answer. I found the following result as not functioning for what I am looking for

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

推荐答案

问题是,一旦您单击"单选按钮,从而导致调用QMessageBox::exec,您的代码将停止运行,直到用户单击为止.上的按钮.

The problem is that once you've "clicked" on your radio button, which results in QMessageBox::exec being called, your code stops running until the user clicks on of the buttons.

您可以通过在单击单选按钮之前 启动计时器来模拟用户单击按钮.

You can simulate the user clicking a button by starting a timer before you click on the radio button.

在计时器的回调函数中,您可以使用 QApplication::activeModalWidget() 获取指向消息框的指针,然后在其上调用close.

In the callback function for the timer you can use QApplication::activeModalWidget() to obtain a pointer to the message box, and then just call close on it.

QTimer::singleShot(0, [=]()
    {
        QWidget* widget = QApplication::activeModalWidget();
        if (widget)
            widget->close();
    });

如果要在消息框上按特定键,可以使用 QCoreApplication::postEvent 将按键事件发布到消息框中

If you want to press a specific key on the message box, you can use QCoreApplication::postEvent to post a key event to the message box

QTimer::singleShot(0, [=]()
    {
        int key = Qt::Key_Enter; // or whatever key you want

        QWidget* widget = QApplication::activeModalWidget();
        if (widget)
        {
            QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier); 
            QCoreApplication::postEvent(widget, event);
        }
    });

因此,如何将其与您提供的示例代码联系起来:

So in terms of how this ties into the sample code you gave:

void testui1()
{
    Form1* myform = new Form1();
    myform->show();

    QTimer::singleShot(0, [=]()
        {
            QWidget* widget = QApplication::activeModalWidget();
            if (widget)
                widget->close();
            else
                QFAIL("no modal widget");
        });

    QTest::mouseClick(myform->radioButton01, Qt::LeftButton, Qt::NoModifier, QPoint(), 100);
}

将以上所有内容结合在一起的示例应用程序:

#include <QApplication>
#include <QMainWindow>
#include <QHBoxLayout>
#include <QPushButton>
#include <QTimer>
#include <QMessageBox>
#include <iostream>

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QMainWindow window;

    QWidget widget;
    window.setCentralWidget(&widget);

    QHBoxLayout layout(&widget);

    QPushButton btn("go");
    layout.addWidget(&btn);

    QObject::connect(&btn, &QPushButton::clicked, [&]()
        {
            QTimer::singleShot(0, [=]()
                {
                    QWidget* widget = QApplication::activeModalWidget();
                    if (widget)
                    {
                        widget->close();
                    }
                    else
                    {
                        std::cout << "no active modal\n";
                    }
                });

            QMessageBox(
                QMessageBox::Icon::Warning,
                "Are you sure?",
                "Are you sure?",
                QMessageBox::Yes | QMessageBox::No,
                &window).exec();
        });

    window.show();
    return app.exec();
}

单击 Go 似乎没有任何反应,因为QMessageBox立即关闭.

要证明该消息框已显示然后关闭,您可以将对QTimer::singleShot的调用时间增加到诸如1000的值.现在它将显示消息框1秒钟,然后计时器将其关闭.

To prove that the message box is shown and then closed you can increase the time in the call to QTimer::singleShot to a value such as 1000. Now it will show the message box for 1 second, and then it will be closed by the timer.

这篇关于Qt Auto-UI测试由于消息框而停止.如何模拟在消息框上输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆