QTestLib框架
QTestLib是QT的单元测试框架。它的使用步骤为:
- 首先继承 QObiect 类并添加私有的槽。每个私有的槽就是一个测试函数。
- 然后使用 QTest::qExec执行测试对象中的所有测试函数。实际上只要将测试函数声明私有的槽就会自动执行。
注意:以下四个私有槽函数,是自带的,完成框架本身的业务逻辑。
数据驱动测试
正常来说一个c++类要进行测试就需要检查它头文件定义函数的运行情况,而绝大部分都需要参数的传入;那么针对于日常的c++对象来说,进行测试的步骤为:
- 确保使用QDECLARE METATYPE(类名)将需要测试的类定义为元类型,方便模板函数的引用(也就是QTest的函数)。
- 使用自定义类(可以直接在cpp文件中)继承 QObiect 类并在私有槽中添加测试函数,然后在测试函数主体进行测试的业务逻辑。
建立数据函数
如果需要用到数据进行测试,则需要定义 建立数据函数,该函数的名必须为:测试函数名_data。
给个例子:
void MyTest::toArea_data()
{//定义测试数据列QTest::addColumn<Area>("area");QTest::addColumn<double>("r");//建立测试数据QTest::newRow("1")<<Area(1)<<3.14;QTest::newRow("2")<<Area(2)<<12.56;QTest::newRow("3")<<Area(3)<<28.26;
}
-
QTest::addColumn<Area>("area");
这行代码使用QTest::addColumn
函数为测试添加一个新的列,列的数据类型是Area
(假设Area
是一个自定义类型,可能是一个结构体或类)。列的名称是"area"
。这意味着在后续的测试数据中,每一行都将包含一个Area
类型的值。 -
QTest::addColumn<double>("r");
类似地,这行代码添加了一个名为"r"
的列,其数据类型是double
。这表示每一行测试数据还将包含一个双精度浮点数。 -
QTest::newRow("1")<<Area(1)<<3.14;
这行代码使用QTest::newRow
函数添加了一行新的测试数据。"1"
是这行数据的标识符或名称,用于在测试报告中标识这行数据。<<Area(1)<<3.14
是将数据添加到这行的语法,这里表示这行数据的"area"
列的值是Area(1)
(假设Area
有一个接受单个整数参数的构造函数),而"r"
列的值是3.14
。 -
QTest::newRow("2")<<Area(2)<<12.56;
这行代码添加了第二行测试数据,与上一行类似,但"area"
列的值是Area(2)
,"r"
列的值是12.56
。 -
QTest::newRow("3")<<Area(3)<<28.26;
类似地,这行代码添加了第三行测试数据,"area"
列的值是Area(3)
,"r"
列的值是28.26
。
测试函数
void MyTest::toArea()
{QFETCH(Area,area);QFETCH(double,r);QVERIFY(qAbs(area.CountArea()-r)<0.000001);QVERIFY2(true,"err");
}
-
QFETCH(Area,area);
QFETCH
宏用于从当前测试行中获取名为"area"
的列的数据,并将其存储在名为area
的变量中。这里,Area
是数据类型,area
是变量名(尽管它与列名相同,但在这里它作为变量使用)。 -
QFETCH(double,r);
类似地,这行代码从当前测试行中获取名为"r"
的列的数据,并将其存储在名为r
的double
类型变量中。 -
QVERIFY(qAbs(area.CountArea()-r)<0.000001);
这行代码执行一个断言。qAbs
函数计算area.CountArea()
返回的值与r
之间的差的绝对值。QVERIFY
宏检查这个绝对值是否小于0.000001
(一个非常小的数,用于表示允许的误差范围)。如果条件为真(即,差的绝对值小于指定的误差),则断言通过,测试继续。如果条件为假,则断言失败,测试将报告错误。这里假设Area
类有一个名为CountArea
的成员函数,它返回该区域的某种度量(可能是面积,但具体取决于Area
类的实现)。 -
QVERIFY2(true,"err");
这行代码执行另一个断言,但这次使用的是QVERIFY2
宏。QVERIFY2
与QVERIFY
类似,但它允许你指定一个错误消息,如果断言失败,该消息将被打印出来。在这个特定的例子中,断言的条件是true
,这意味着这个断言总是会通过,无论Area
类或r
的值如何。错误消息"err"
在这个断言中不会被使用,因为断言总是会通过
QFETCH
宏通常与 QTest::addColumn
方法一起使用,后者在测试类的 测试函数名
或 测试函数名_data
函数中调用,用于为测试数据集添加列。然后,每个测试用例可以使用 QFETCH
来检索这些列中的值。
整体代码
#include <QtTest>
#include <QCoreApplication>
#include <QTest>
#include"Area.h"
// add necessary includes hereclass MyTest : public QObject
{Q_OBJECTpublic:MyTest();~MyTest();
private slots:void toArea();void toArea_data();};MyTest::MyTest()
{}MyTest::~MyTest()
{}
void MyTest::toArea_data()
{//定义测试数据列QTest::addColumn<Area>("area");QTest::addColumn<double>("r");//建立测试数据QTest::newRow("1")<<Area(1)<<3.14;QTest::newRow("2")<<Area(2)<<12.56;QTest::newRow("3")<<Area(3)<<28.26;
}
void MyTest::toArea()
{QFETCH(Area,area);QFETCH(double,r);QVERIFY(qAbs(area.CountArea()-r)<0.000001);QVERIFY2(true,"err");
}QTEST_APPLESS_MAIN(MyTest)#include "tst_mytest.moc"
结果:
性能测试
就是+个QBENCHMARK宏
改变的测试函数如下:
void MyTest::toArea()
{QBENCHMARK{QFETCH(Area,area);QFETCH(double,r);QVERIFY(qAbs(area.CountArea()-r)<0.000001);QVERIFY2(true,"err");}
}
结果:
其含义是测试代码运行了524288 次,总时间为57毫秒(ms),每次运行的平均时间为0.00010毫秒(ms)。