【问题标题】:Qt Gui Unit Test: Must construct a QApplication before a QPaintDeviceQt Gui 单元测试:必须在 QPaintDevice 之前构造 QApplication
【发布时间】:2013-05-23 10:00:01
【问题描述】:

我设法使用this tutorial 编写了一个“Gui 单元测试”。但是,当我编译我的代码时,我得到了这个:

PASS   : testUnits::initTestCase()
PASS   : testUnits::toUpper()
QFATAL : testUnits::testGui() QWidget: Must construct a QApplication before a QPaintDevice
FAIL!  : testUnits::testGui() Received a fatal error.
Unknown file(0) : failure location
Totals: 2 passed, 1 failed, 0 skipped
********* Finished testing of testUnits *********

为什么它给我:必须在 QPaintDevice 之前构造一个 QApplication ?

【问题讨论】:

  • 您可能遗漏了一些东西,请确保您遵循链接到的教程的每个细节。我没有使用过那个单元测试框架,但是QTEST_MAIN(TestGui) 应该足够聪明,可以在测试 GUI 时创建一个 QApplication 实例,除非整个框架都坏了。
  • 另一件事,你有机会使用 Qt5 吗? Qt4 和 Qt5 之间的差异足以肯定会破坏该单元测试框架,如果存在的话,您需要一个 Qt5 版本。
  • 您是否在使用 QtGui 库(即 QT += gui 在您的 .pro 中)?
  • @hyde:你是对的,我错过了在调用我的 Gui 单元测试之前放置我的 QApplication。因此,它正在寻找 QPaintDevice(即:QEditLine),而没有可用的 QApplication(请参阅我自己的答案中的代码)。再次感谢您提到 Qt4 和 Qt5 的差异问题,我会记住这一点,因为我正在研究两个 Qts,一个是 Qt4,另一个是 Qt5
  • @cmannett85:不,我不是,但如果我必须这样做,为什么我的代码可以工作。甚至在此之前,我可以向您保证我的单元测试工作正常,因为它给了我一个“失败”的输出结果。我的问题是为什么它失败了?但是既然你提到了,那QT += gui到底做了什么?

标签: c++ qt unit-testing qt-creator


【解决方案1】:

现在可以了,这是我的 Gui 单元测试函数定义:

void testUnits::testGui(){
    QLineEdit lineEdit;
    QTest::keyClicks(&lineEdit,"hellow world");
    QCOMPARE(lineEdit.text(), QString("hello world"));
}

这是我的 main() 在解决问题之前的样子:

int main(int argc, char *argv[])
{

    testUnits testString;
    QTest::qExec(&testString, argc, argv);

    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

所以,当我编译代码时,它会在构建 QApplication 之前执行单元测试。

因此,我将 QTest::qExec() 放在 QApplication 之后,现在它可以工作了,main() 看起来像这样:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    testUnits testString;
    QTest::qExec(&testString, argc, argv);

    return a.exec();
}

【讨论】:

  • 通过像这样解开 QTEST_MAIN 宏,我能够在实例化 QApplication 之前运行代码,如果您想在应用对象上设置属性 Qt::AA_ShareOpenGLContexts,这是一个要求。谢谢!
【解决方案2】:

最好不要手动定义自己的main。所有测试逻辑,包括所需的先决条件,都应在测试对象(带有test* 插槽的QObject 子类)本身内进行。详情请见QTestLib manual

如果您这样做了,那么只需使用QTEST_MAIN 就可以做正确的事情并为您节省一些时间。

【讨论】:

  • 这样做的问题是它的可扩展性不好,因为你不能将分组的测试分开到它们自己的标题中——所有东西都必须是同一个测试对象的一部分。我的个人项目的单元测试覆盖率相对较差,但是尝试使用具有数百个良好的 doxygen 单元测试的单个标头是一个巨大的痛苦(即使您可以分离出源文件),我无法想象它会有多糟糕进行数千次测试...
  • 我不熟悉您的用例,但显而易见的答案是将测试拆分为多个类(因此还有多个独立的可执行文件)。 QTestLib 默认支持make check 目标。
猜你喜欢
  • 2016-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多