Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Qt'进行测试;s QTestLib模块_Qt_Unit Testing_Qttest - Fatal编程技术网

使用Qt'进行测试;s QTestLib模块

使用Qt'进行测试;s QTestLib模块,qt,unit-testing,qttest,Qt,Unit Testing,Qttest,我开始用Qt的单元测试系统编写一些测试 你通常是如何组织考试的?它是每个模块类一个测试类,还是用一个测试类测试整个模块?Qt文档建议遵循前一种策略 我想为一个模块编写测试。模块只提供一个将由模块用户使用的类,但是在其他类中抽象了很多逻辑,除了测试公共类之外,我还想测试这些逻辑 问题在于,Qt建议的运行测试的方法涉及QTEST\u MAIN宏: QTEST_MAIN(TestClass) #include "test_class.moc" 最终一个测试程序只能测试一个测试类。为模块中的每个类创建

我开始用Qt的单元测试系统编写一些测试

你通常是如何组织考试的?它是每个模块类一个测试类,还是用一个测试类测试整个模块?Qt文档建议遵循前一种策略

我想为一个模块编写测试。模块只提供一个将由模块用户使用的类,但是在其他类中抽象了很多逻辑,除了测试公共类之外,我还想测试这些逻辑

问题在于,Qt建议的运行测试的方法涉及
QTEST\u MAIN
宏:

QTEST_MAIN(TestClass)
#include "test_class.moc"
最终一个测试程序只能测试一个测试类。为模块中的每个类创建测试项目有点糟糕

当然,可以查看
QTEST_MAIN
宏,重写它,然后运行其他测试类。但是有什么东西是现成的吗

到目前为止,我是手工完成的:

#include "one.h"
#include "two.h"

int main(int argc, char *argv[]) 
{ 
    QCoreApplication app(argc, argv); 
    TestOne one;
    QTest::qExec(&one, argc, argv);
    TestOne two;
    QTest::qExec(&two, argc, argv);
}

是的,QTest强制使用有点奇怪的测试结构,通常不如googletest/Mock框架。对于一个项目,我被迫使用QTest(客户需求),以下是我如何使用它:

  • 我将所有测试作为一个subdir模板项目一起编译
  • 为了更容易地创建新的测试,我使用每个test.pro文件中包含的common.pri文件共享了很多项目配置
  • 如果可能,我共享objectfiles目录以加速编译
  • 我使用batch+awk+sed脚本运行它们 设置这四个点非常简单,使QTest的使用几乎令人愉快。您是否在运行多个测试时遇到了上述配置无法解决的问题


    PS:按您的方式运行测试,即调用多个QTest::qExec会导致-o命令行开关出现问题-您只会得到上一个测试类的结果。

    在我们使用QTest的设置中,我们做了一些事情使其更好

    • 定义QObject的子类,该子类用作任何新单元测试类的基类
    • 在该类的构造函数中,我们将测试实例添加到静态测试列表中,并在析构函数中删除它
    • 然后,我们有一个静态函数,它循环测试并使用
      QTest::qExec()
      运行它们。(我们累积每次返回的值,并从函数中返回。)
    • main()
      调用此函数,并将结果作为成功/失败返回
    • 最后,在特定测试本身的编译单元中,我们通常包括该类的静态实例
    此设置意味着该类将在运行
    main()
    之前实例化,因此它将被添加到要在main运行时进行测试的类列表中。该框架要求您只需正确继承类,并实例化一个静态实例(如果您总是希望它运行的话)


    我们偶尔也会创建其他可选的测试,这些测试是基于命令行开关添加的。

    通常我会组织测试,测试中的每个类都有一个测试可执行文件

    最终一个测试程序是 能够只测试一个测试 班级

    这是一件好事。它将您的测试彼此隔离,防止一个测试中的崩溃之类的事情阻塞所有其他测试。这种崩溃可能是由测试中的几个类中的一个公共组件引起的。然后,故障模式将提示您问题的根本根源。基本上,如果您的测试彼此独立,您就可以获得更好的故障诊断信息

    使设置多个可执行文件和单独运行每个测试变得容易。使用测试运行程序生成所有测试进程

    更新:

    MyTestClass1 t1;   t1.run();
    MyTestClass2 t2;   t2.run();
    //etc...
    
    我在这件事上有些改变了主意。一旦你有了一个包含大量测试的大程序,链接数百个测试可执行文件就会变得非常缓慢。我的新偏好是将库的所有测试放入可执行文件中,并使用传递给测试可执行文件的命令行参数选择要调用的测试


    这将可执行文件的数量从数百个减少到几十个,但保留了单独运行测试的优势。

    与@cjhuitt发布的答案相关

    这是一个不需要手动调用每个测试对象的示例

    我尽量避免这样的事情:

    MyTestClass1 t1;   t1.run();
    MyTestClass2 t2;   t2.run();
    //etc...
    
    我的解决方案是让测试对象从添加到静态列表的基类继承 然后主程序执行该列表中的所有测试对象。这样,就不需要更改任何支持框架的代码。唯一改变的是测试类本身

    我是这样做的:

    qtestsuite.h-测试对象的基类

    #ifndef QTESTSUITE_H
    #define QTESTSUITE_H
    
    #include <QObject>
    #include <vector>
    
    class QTestSuite : public QObject
    {
        Q_OBJECT
    public:
        static std::vector<QObject*> m_suites;
    
    public:
        explicit QTestSuite();
    
    };
    
    #endif // QTESTSUITE_H
    

    嗨,卡莱布,还在挣扎。您是否有愿意分享的示例代码?谢谢。两年来,我在几个测试项目中使用了这种方法,但现在我遇到了以下静态初始化顺序问题:
    static MyTestSuite1实例
    可以在
    m_套件
    之前初始化。因此,最好让m_套件是一个返回对静态成员的引用的函数:
    std::vector&QTestSuite::mSuites(){static std::vector INST;return INST;}
    注意,如果您编写这样的测试,Qt Creator的自动测试插件在查找宏“QTEST_MAIN”时将无法找到并运行它们(我自己刚刚发现)“QTEST_APPLESS_MAIN”和“QTEST_GUILESS_MAIN”。见详情。
    #include "qtestsuite.h"
    
    #include <QtTest/QtTest>
    #include <iostream>
    
    int main(int, char**)
    {
        int failedSuitesCount = 0;
        std::vector<QObject*>::iterator iSuite;
        for (iSuite = QTestSuite::m_suites.begin(); iSuite != QTestSuite::m_suites.end(); iSuite++)
        {
            int result = QTest::qExec(*iSuite);
            if (result != 0)
            {
                failedSuitesCount++;
            }
        }
        return failedSuitesCount;
    }
    
    #include "qtestsuite.h"
    
    #include <QtTest/QtTest>
    
    class MyTestSuite1: public QTestSuite
    {
         Q_OBJECT
    private slots:
        void aTestFunction();
        void anotherTestFunction();
    };
    
    void MyTestSuite1::aTestFunction()
    {
        QString str = "Hello";
        QVERIFY(str.toUpper() == "this will fail");
    }
    
    void MyTestSuite1::anotherTestFunction()
    {
        QString str = "Goodbye";
        QVERIFY(str.toUpper() == "GOODBYE");
    }
    
    static MyTestSuite1 instance;  //This is where this particular test is instantiated, and thus added to the static list of test suites
    
    #include "mytestsuite1.moc"
    
    qmake -project "CONFIG += qtestlib"