QTest从入门到精通(1)
如何快速使用上QTest进行单元测试
按图索骥
1. 目录结构
2. 新建项目选择其他项目->AutoTestProject
3. 工程配置
4. 在主工程中新建,选择主工程
5. 生成的单元测试
6. 代码结构
认识生成模版
单元测试配置文件QTest_unittest.pro
QT += testlib #将 Qt 测试库添加到项目中,以便使用 Qt 的测试功能。
QT -= gui #从项目中移除 GUI 相关模块,因为这是一个控制台应用程序,不需要图形界面。
#qt:确保项目使用 Qt 框架。
#console:将应用程序设置为控制台程序。
#warn_on:在编译时启用警告信息。
#depend_includepath:将所有依赖项的 INCLUDEPATH 添加到项目中。
#testcase:将项目设置为一个测试用例。
CONFIG += qt console warn_on depend_includepath testcase
CONFIG -= app_bundle #取消应用程序捆绑包设置,避免在 macOS 上创建一个 .app 捆绑包
TEMPLATE = app #指定项目类型为应用程序
SOURCES += tst_uitest.cpp #将测试源文件 tst_uitest.cpp 添加到项目中。
tst_uitest.cpp实现
这个示例展示了如何使用 Qt 测试框架创建一个简单的测试用例。Qt 测试框架是用于对 Qt 和 C++ 应用程序进行单元测试的工具。下面是关于这个示例代码及其原理的详细说明:
-
包含必要的头文件:包括 QtTest 和 QCoreApplication,它们提供了 Qt 测试框架和应用程序核心组件的类和功能。
-
创建一个从 QObject 继承的测试类(例如 qwertyuwerty)。QObject 提供了对象模型特性,如信号-槽处理、对象树以及对象属性等。Q_OBJECT 宏用于启用类的 Qt 元对象特性。
-
在测试类中定义构造函数、析构函数以及三个私有槽(private slots)作为测试方法:initTestCase()、cleanupTestCase() 和 test_case1()。
- initTestCase(): 在运行整个测试套件之前执行一些初始化操作。
- cleanupTestCase(): 在运行完所有测试用例后执行一些清理操作。
- test_case1(): 是实际测试用例,可以在里面编写测试逻辑。您可以添加更多的测试方法。
-
实现这些方法。目前,这些方法为空,您需要为它们提供具体实现。
-
使用 QTEST_MAIN(qwertyuwerty) 宏生成 main() 函数。这个宏会创建一个名为 main() 的函数,该函数负责运行测试类(qwertyuwerty)及其中的测试槽(即测试用例)。它会将测试结果输出到控制台。
-
包含 "tst_qwertyuwerty.moc" 文件,以便 Qt 元对象编译器(MOC)处理。这个文件是由 MOC 自动生成的,用于处理 QObject 派生类中的信号、槽和属性等元对象特性。在这种情况下,它主要负责处理测试方法的信号-槽调用。
要执行这个测试用例,您需要使用 Qt Creator 创建一个新的 Qt Test 项目,并将这段代码添加到项目源文件中。然后编译并运行项目。测试框架会自动运行所有定义的测试槽,并报告成功或失败的测试数量。
Note:
要增加新的测试方法,需要在private slots: 下增加,这样才会执行时被系统默认调用
宏QTEST_MAIN
定义如下
#define QTEST_MAIN_IMPL(TestObject) \
TESTLIB_SELFCOVERAGE_START(#TestObject) \
QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<TestObject>(); \
QGuiApplication app(argc, argv); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
TestObject tc; \
QTEST_SET_MAIN_SOURCE_PATH \
return QTest::qExec(&tc, argc, argv);
#define QTEST_MAIN(TestObject) \
int main(int argc, char *argv[]) \
{ \
QTEST_MAIN_IMPL(TestObject) \
}
重点关注一下QTest::qExec(&tc, argc, argv);
宏QTEST_GUILESS_MAIN
字面意思就是没有集成GUI
#define QTEST_GUILESS_MAIN(TestObject) \
int main(int argc, char *argv[]) \
{ \
TESTLIB_SELFCOVERAGE_START(#TestObject) \
QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)<TestObject>(); \
QCoreApplication app(argc, argv); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
TestObject tc; \
QTEST_SET_MAIN_SOURCE_PATH \
return QTest::qExec(&tc, argc, argv); \
}
宏QTEST_APPLESS_MAIN
终端程序
#define QTEST_APPLESS_MAIN(TestObject) \
int main(int argc, char *argv[]) \
{ \
TESTLIB_SELFCOVERAGE_START(TestObject) \
TestObject tc; \
QTEST_SET_MAIN_SOURCE_PATH \
return QTest::qExec(&tc, argc, argv); \
}
上面三个宏最要的是功能就是现实了main函数
编写代码
将测试类引入
#include "calculator.h"
#include "CalculatorTest.h"
#include <QDebug>
void CalculatorTest::initTestCase()
{
qDebug() << "initTestCase";
}
void CalculatorTest::cleanupTestCase()
{
qDebug() << "cleanupTestCase";
}
void CalculatorTest::testAdd()
{
Calculator cls;
QCOMPARE(cls.add (3,4),7);
}
优化
使用了上面的宏定义就只能有一个测试类了,显然不符合正常的测试开发流程,我们需要多个测试类对不同的测试场景覆盖
所以修改代码如下
1. 创建main,cpp,定义main函数
2. 将测试类分开为.h,.cpp文件,引入头文件
调用代码就会自动执行测试代码,从前面的宏定义也能看到
MyTest test;
QTest::qExec(&test, argc, argv);
CalculatorTest suite1;
QTest::qExec(&suite1, argc, argv);
WindowTest witest;
QTest::qExec(&witest, argc, argv);
这样就可以实现多个测试类同时运行,如果先单独测试一个类,可以写在最前面然后return 0 ,不过还有更加简单的方法,下面介绍
运行测试用例
运行单元测试插件即可
我们可以直观的看到运行结果,用例是否成功
引用
本文来自博客园,作者:严_青,转载请注明原文链接:https://www.cnblogs.com/zhao-jie-li/articles/17268274.html