使用Qt Test测试模态对话框

Ign*_*tor 7 qt unit-testing modal-dialog

我正在尝试使用QTestLib为GUI应用程序编写单元测试.问题是其中一个插槽使用创建模式对话框exec() ,我发现没有可能与对话框进行交互.

创建对话框的插槽连接到QAction.所以第一个问题是当我在测试中触发QAction时测试阻塞,因为这会导致调用exec().因此,我尝试创建一个执行交互的QThread.但是,这没有帮助.

我已经尝试过的事情(都是在"交互助手"线程中执行的):

  1. 使用发送关键点击次数 QTest::keyClicks()
    • 错误消息"QCoreApplication :: sendEvent()中的结果:无法将事件发送到不同线程拥有的对象"
  2. 发布QKeyEvents使用 QCoreApplication::postEvent()
    • 不起作用,即没有任何反应.我猜是因为事件最终出现在拥有对话框的线程的事件循环中,在对话框关闭并exec()返回之前不会到达. 见下面的编辑
  3. 使用在对话框上调用Slots QMetaObject::invokeMethod()
    • 不起作用,即没有任何反应.我想是因为同样的原因postEvent()不起作用. 见下面的编辑

所以问题是:有没有办法以编程方式与使用该exec()方法打开的模态对话框进行交互?

编辑:实际上,方法3正在运行.问题是另一个问题:我将参数传递invokeMethod()给"交互助手"线程,由于某种原因,访问参数不起作用(我没有SEG错误,但它们只是空的).我想方法2也有效,我只是遇到与方法3相同的问题,但我没有测试过.

Sam*_*mer 6

我在命令行应用程序中使用的解决方案是使用用于GUI的Qt库singleShot,正如这个答案所暗示的那样.在这些情况下,它看起来像这样:

QCoreApplication app(argc, argv);

// ...

QTimer::singleShot(0, &app, SLOT(quit()));
return app.exec();
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下,我想它看起来像这样:

QDialog * p_modalDialog = getThePointer(); // you will have to replace this with
                                           // a real way of getting the pointer

QTimer::singleShot(0, p_modalDialog, SLOT(accept()));

p_modalDialog->exec(); // called somewhere else in your case
                       // but it will be automatically accepted.
Run Code Online (Sandbox Code Playgroud)


ale*_*sdm 5

您可以通过延迟执行直到对话框事件循环开始来将交互保持在同一线程中。

例如,在exec()调用之前,您可以使用QTimer::singleShot0 作为间隔或QMetaObject::invokeMethod使用连接类型Qt::QueuedConnection来调用显示对话框时需要执行的槽。