C++ Qt自动UI测试因messagebox而停止。如何在messagebox上模拟输入?
我的任务是为正在开发的软件编写一个自动化的UI测试。发生这种情况时,会有单选按钮触发messagebox,它会停止我的自动测试,直到我手动确认它(按ENTER键)。问题是我不知道如何调用新调用的messagebox,然后通过C++ Qt自动UI测试因messagebox而停止。如何在messagebox上模拟输入?,c++,qt,user-interface,testing,automated-tests,C++,Qt,User Interface,Testing,Automated Tests,我的任务是为正在开发的软件编写一个自动化的UI测试。发生这种情况时,会有单选按钮触发messagebox,它会停止我的自动测试,直到我手动确认它(按ENTER键)。问题是我不知道如何调用新调用的messagebox,然后通过QTest::keyClick(,QtKey::Key\u Enter)确认它并让我的自动测试继续运行 我正在使用QWidgets、QApplication、Q_对象和QtTest。 我将提供与我正在使用的代码类似的代码: void testui1(){ Form1* myf
QTest::keyClick(,QtKey::Key\u Enter)确认它代码>并让我的自动测试继续运行
我正在使用QWidgets、QApplication、Q_对象和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
...
}
如何编写脚本以自动确认消息框?消息框只是[OK]类型,因此我不需要它返回我是否按了Yes或No。方法需要知道它应该按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);
}
}
QWidgetList allToplevelWidgets=QApplication::topLevelWidgets();
foreach(QWidget*w,allToplevelWidgets){
如果(w->inherits(“QMessageBox”)){
QMessageBox*mb=qobject_cast(w);
QTest::keyClick(mb,Qt::Key\u Enter);
}
}
问题在于,一旦“单击”单选按钮,导致调用QMessageBox::exec
,代码就会停止运行,直到用户单击其中一个按钮
通过在单击单选按钮之前启动计时器,可以模拟用户单击按钮
在计时器的回调函数中,您可以使用该函数获取指向消息框的指针,然后只需对其调用close
QTimer::singleShot(0, [=]()
{
QWidget* widget = QApplication::activeModalWidget();
if (widget)
widget->close();
});
如果要按消息框上的特定键,可以使用向消息框发布键事件
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);
}
});
因此,关于这与您给出的示例代码的关系:
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();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符**argv)
{
QApplication应用程序(argc、argv);
qmain窗口;
QWidget小部件;
setCentralWidget(&widget);
QHBoxLayout布局(和小部件);
QPushButton btn(“go”);
layout.addWidget(&btn);
QObject::connect(&btn,&QPushButton::单击,[&]()
{
QTimer::单次快照(0,[=]()
{
QWidget*widget=QApplication::activeModalWidget();
如果(小部件)
{
窗口小部件->关闭();
}
其他的
{
std::你的代码能找到消息框吗?请澄清。我怀疑它能找到。在任何情况下,是否有一段脚本可以找到该消息框?你的代码看起来有效:迭代所有顶级窗口。我可能怀疑模式消息框阻塞了事件循环,因此在消息框打开时你的代码不会执行。我相信你需要要注册一个将关闭消息框的计时器-请参见下面对我的答案所做的编辑谢谢你的朋友!但是在文章QTimer::singleShot(0,[=])中
应该用等待时间的值替换0。在我的例子中,我将150作为毫秒值放入其中。它可以工作!@Unit1添加任意延迟非常脆弱且容易出错-150ms在您的开发机器上对您有效,但它能在每台机器上工作吗?我会坚持延迟0,但添加对QCoreApplication::proces的调用sEvents();
在检查活动模式(未测试,只是一个想法,如果它有效,将远优于使用延迟)之前,延迟=0对我不起作用。调试脚本已停止。我在将延迟设置为150毫秒之前对其进行了测试。|您建议我将QCoreApplication::processEvents()放置在何处
?在鼠标单击调用messagebox之前,或在该QTimer内?@Unit1在调用获取活动模式前的计时器内。QCoreApplication::processEvents();
无效。我确实将其放在了activemodalwidget之前。消息框再次出现并停止了自动化。