Qt:从多个测试类运行单元测试并总结所有测试的输出

15

Qt提供了QTest,并且有一些文档,例如官方教程

然而,QTest鼓励您将单元测试组织为单独的可执行文件。这里有一个特殊的宏,可以生成main()QTEST_MAIN()

说实话,我真的不喜欢这种方法:通常,一次运行所有测试更有用,以确保最近的更改没有破坏任何东西。有时候,屏蔽某些测试或执行某个单独的测试确实有用,但这是例外而不是规则。

所以,我想一次运行所有测试。好吧,我可以编写自己的main(),执行我想要的所有测试,比如像这样:

int main(int argc, char **argv)
{
   int status = 0;

   //-- run all tests
   {
      TestHTCodecISO14230 tc;
      status |= QTest::qExec(&tc, argc, argv);
   }

   {
      TestHTDataMsg tc;
      status |= QTest::qExec(&tc, argc, argv);
   }

   return status;
}

它确实运行了所有测试,但问题是我没有方便的所有测试的摘要。比如,对于上面的两个测试,我有两个单独的摘要:

********* Start testing of TestHTCodecISO14230 *********
Config: Using QtTest library 5.4.1, Qt 5.4.1 (i386-little_endian-ilp32 shared (dynamic) release build; by GCC 4.6.1)
PASS   : TestHTCodecISO14230::initTestCase()
PASS   : TestHTCodecISO14230::decode_summary()
PASS   : TestHTCodecISO14230::encode()
PASS   : TestHTCodecISO14230::decode_encoded()
PASS   : TestHTCodecISO14230::cleanupTestCase()
Totals: 5 passed, 0 failed, 0 skipped, 0 blacklisted
********* Finished testing of TestHTCodecISO14230 *********
********* Start testing of TestHTDataMsg *********
Config: Using QtTest library 5.4.1, Qt 5.4.1 (i386-little_endian-ilp32 shared (dynamic) release build; by GCC 4.6.1)
PASS   : TestHTDataMsg::initTestCase()
PASS   : TestHTDataMsg::test1()
PASS   : TestHTDataMsg::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted
********* Finished testing of TestHTDataMsg *********

当发生错误时,返回的status将是非零值,这一事实确实有帮助,但如果我也有摘要,那就更有帮助:

Totals: 8 passed, 0 failed, 0 skipped, 0 blacklisted

根据我的观察,这似乎是不可能的:我找不到以编程方式获取测试通过、失败、跳过和黑名单测试数量的方法:qExec()只是QTest命名空间中的一个函数,因此在它执行后获取其他信息似乎是不可能的。

嗯,可以解析输出字符串,但是...呃...

对我来说,这看起来像是设计不良。也许最好将QTest作为一个类,然后实例化它并将一些测试类提供给它。接着,可以从一个实例中收集一些额外的信息。

或者,也许我漏掉了什么。

所以问题是:是否可以使用QTest获取所有单元测试类的汇总输出?


“TestHTCodecISO14230”和“TestHTDataMsg”不是你的类吗?为什么不能扩展它们来处理失败的测试计数? - vahancho
1个回答

9

正如我在评论中所写的,我会按照以下方式构建我的测试类:

class MyTests: public QObject
{
    Q_OBJECT
public:
    MyTests() : m_executed(0), m_failed(0)
private slots:
    [..]
    // This function will be called after each test
    void cleanup()
    {
        m_executed++;
        if (currentTestFailed()) {
            m_failed++;
        }        
    }

    // Output the summary of the test execution.
    void report() const
    {
        qDebug() << "Totals:"
                 << m_executed - m_failed  << "passed,"
                 << m_failed << "failed";
    }
private:
    int m_executed;
    int m_failed;
};

如果您有多个MyTests类的实例,您可以扩展其API并总结执行结果,从而产生全局测试执行报告。只需使用C++类的全部力量即可。


谢谢你的回答,但这样我就不能使用QCOMPARE()宏和相关函数了;我得想办法重新实现它们。我会尝试的。 - Dmitry Frank
1
@DmitryFrank,但为什么您不能使用QCOMPARE()?请解释一下。 - vahancho
@vahancho,你会如何实现currenttestfailed()函数? - Moia
@Moia,你是什么意思?你不需要实现它。这是QTest类的一部分。执行测试后,您可以检查它是否失败。 - vahancho
@vahancho,我的错,我以为这是一个用户定义的类,我不知道它是一个QTest方法。 - Moia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接