首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Qt的QTestLib模块进行测试

使用Qt的QTestLib模块进行测试
EN

Stack Overflow用户
提问于 2010-05-01 21:00:27
回答 4查看 13.1K关注 0票数 12

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

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

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

问题是Qt提出的运行测试的方法涉及到QTEST_MAIN宏:

代码语言:javascript
复制
QTEST_MAIN(TestClass)
#include "test_class.moc"

最终,一个测试程序能够只测试一个测试类。而且,为模块中的每个类创建测试项目也有点糟糕。

当然,您可以查看一下QTEST_MAIN宏,重写它,然后运行其他测试类。但是有没有什么东西可以开箱即用呢?

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

代码语言:javascript
复制
#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);
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-05-03 02:50:28

是的,QTest强制使用了一些奇怪的测试结构,并且通常比Google Test/Mock Framework差。对于一个项目,我被迫使用QTest (客户需求),下面是我是如何使用它的:

  1. I编译所有的测试作为一个子目录模板项目
  2. 为了使创建新的测试更容易,我使用common.pri文件共享了大量的项目配置,我在每个测试.pro文件中都包含了
  3. 如果可能的话,我共享对象文件目录以加快编译
  4. 我使用一个batch+awk+sed脚本来运行它们。

设置这四个点非常容易,并且使QTest的使用变得几乎令人愉快。在运行多个测试时,您是否遇到了上述配置无法解决的问题?

PS:以你所做的方式运行测试,比如调用多个QTest::qExec会导致-o命令行开关出现问题--你只能得到最后一个测试类的结果。

票数 4
EN

Stack Overflow用户

发布于 2014-06-29 21:44:36

与@cjhuitt发布的答案相关

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

我尽量避免这样的事情:

代码语言:javascript
复制
MyTestClass1 t1;   t1.run();
MyTestClass2 t2;   t2.run();
//etc...

我的解决方案是让测试对象从一个基类继承,这个基类将自己添加到一个静态列表中,然后主程序执行该列表中的所有测试对象。通过这种方式,不需要更改任何支持框架代码。唯一变化的是测试类本身。

我是这样做的:

qtestsuite.h -测试对象的基类

代码语言:javascript
复制
#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

qtestsuite.cpp

代码语言:javascript
复制
#include "qtestsuite.h"
#include <iostream>

std::vector<QObject*> QTestSuite::m_suites;

QTestSuite::QTestSuite() : QObject()
{
    m_suites.push_back(this);
}

testall.cpp -运行测试

代码语言:javascript
复制
#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;
}

mytestsuite1.cpp -一个示例测试对象,创建更多这样的对象

代码语言:javascript
复制
#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"

另外,要创建.pro文件

代码语言:javascript
复制
qmake -project "CONFIG += qtestlib"
票数 6
EN

Stack Overflow用户

发布于 2010-05-04 02:15:23

在我们的QTest设置中,我们做了一些事情来使它更好。

  • 定义QObject的子类,该子类用作任何新的单元测试类的基类。
  • 在该类的构造函数中,我们将测试的实例添加到测试的静态列表中,然后在析构函数中删除它。
  • 然后我们有一个静态函数,它循环通过测试,并使用QTest::qExec()运行它们。(我们对每次返回的值进行累加,并从函数中返回该值。)
  • main()调用此函数,并将结果作为成功/失败返回。
  • 最后,在特定测试本身的编译单元中,我们通常包含该类的静态实例。

这种设置意味着类将在运行main()之前被实例化,因此当main运行时,它将被添加到要测试的类列表中。该框架要求您只需要正确继承您的类,并实例化一个静态实例,如果您希望它始终运行的话。

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2750005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档