Qt Auto-UI测试由于消息框而停止.如何模拟在消息框上输入? [英] Qt Auto-UI Testing stopping because of messagebox. How to simulate enter on messagebox?
问题描述
我的任务是为正在开发的软件编写自动化的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屋!