Uni*_*it1 2 c++ testing user-interface qt automated-tests
我的任务是为正在开发的软件编写自动化的 UI 测试。碰巧的是,有单选按钮触发了一个消息框,这会停止我的自动化测试,直到我手动确认它(按 ENTER)。问题是我不知道如何调用新调用的消息框,然后确认它QTest::keyClick(<object>, QtKey::Key_Enter);并让我的自动化测试继续运行。
我正在使用 QWidgets、QApplication、Q_OBJECT 和 QtTest。我将提供一个类似于我正在使用的代码:
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
...
}
Run Code Online (Sandbox Code Playgroud)
我究竟如何编写脚本来自动确认消息框?消息框只是一个 [OK] 类型,所以我不需要它来返回我是否按下了 Yes 或 No。一个QTest::keyClick(<target object>, Qt::Key_Enter)方法需要知道它应该按回车键到哪个对象。我尝试包含myform到对象中,但没有奏效。谷歌搜索我没有找到答案。我发现以下结果无法满足我的要求
QWidgetList allToplevelWidgets = QApplication::topLevelWidgets();
foreach (QWidget *w, allToplevelWidgets) {
if (w->inherits("QMessageBox")) {
QMessageBox *mb = qobject_cast<QMessageBox *>(w);
QTest::keyClick(mb, Qt::Key_Enter);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,一旦您“单击”了单选按钮,从而导致QMessageBox::exec被调用,您的代码就会停止运行,直到用户单击这些按钮为止。
您可以通过在单击单选按钮之前启动计时器来模拟用户单击按钮。
在计时器的回调函数中,您可以使用QApplication::activeModalWidget()获取指向消息框的指针,然后调用close它。
QTimer::singleShot(0, [=]()
{
QWidget* widget = QApplication::activeModalWidget();
if (widget)
widget->close();
});
Run Code Online (Sandbox Code Playgroud)
如果要按消息框上的特定键,可以使用QCoreApplication::postEvent将键事件发布到消息框
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);
}
});
Run Code Online (Sandbox Code Playgroud)
因此,就这与您提供的示例代码的关系而言:
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);
}
Run Code Online (Sandbox Code Playgroud)
将以上所有内容放在一起的示例应用程序:
#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();
}
Run Code Online (Sandbox Code Playgroud)
单击Go将看起来像什么也没发生,因为它QMessageBox会立即关闭。
为了证明消息框显示然后关闭,您可以将调用时间QTimer::singleShot增加到一个值,例如1000. 现在它将显示消息框 1 秒钟,然后它将被计时器关闭。