1、常用宏

QBENCHMARK 计算运行时间,多次运行测量

QBENCHMARK_ONCE 计算运行时间,单次运行测量

QCOMPARE 比较是否相等

QEXPECT_FAIL 将下一个QCOMPARE或QVERIFY标记为预期测试,如果预期测试没有通过,可以终止剩余当前单元测试【可设置测试终止或继续】

QFAIL 强制抛出错误并打印信息

QFETCH 创建临时变量,从当前数据表中读取数据

QFETCH_GLOBAL 创建全局变量,从全局数据表中读取数据,必须有initTestCase_data【?】

QFINDTESTDATA 从路径获取测试数据【?】

QSKIP 停止测试,但不会将失败添加到失败日志

QTEST 可替代QFETCH+QCOMPARE的便利写法,不需要QFETCH来生成变量

QTEST_MAIN 创建一个main函数,并实例化应用程序对象和测试用例对象,QT_WIDGETS_LIB->QApplication(Qt+=widgets),QT_GUI_LIB->QGuiApplication(Qt+=gui),其他->QCoreApplication

QTEST_APPLESS_MAIN 与QTEST_MAIN相似但不实例化QApplication

QTEST_GUILESS_MAIN 与QTEST_MAIN相似只实例化QCoreApplication

QTRY_COMPARE_WITH_TIMEOUT 与QCOMPARE相似,但重复执行两个值的比较,直到两个值相等或者达到超时时间

QTRY_COMPARE 执行QTRY_COMPARE_WITH_TIMEOUT,并将超时时间设置为5秒

QVERIFY 判断条件是否为true,如果为true则继续执行测试,否则记录失败日志并且不再执行单元测试

QVERIFY2 与QVERIFY相似,但可以自定义失败日志

QTRY_VERIFY_WITH_TIMEOUT 与QVERIFY相似,但但重复执行条件的判断,直到条件为true或者达到超时时间

QTRY_VERIFY 执行QTRY_VERIFY_WITH_TIMEOUT,并将超时时间设置为5秒

QTRY_VERIFY2_WITH_TIMEOUT 与QVERIFY2相似,但但重复执行条件的判断,直到条件为true或者达到超时时间

QTRY_VERIFY2 执行QTRY_VERIFY2_WITH_TIMEOUT,并将超时时间设置为5秒

QVERIFY_EXCEPTION_THROWN 执行表达式,并判断语句抛出的异常是否与预期异常相等

QWARN 主动添加警告日志(线程安全)

 2、创建Qt自动化测试工程

2.1、新建工程,可选Qt单元测试和Auto Test Project,在高版本中已经没有Qt单元测试这项了,建议选Auto Test Project,两者差不多,只是生成的默认宏不一样

 

 

 

 

 

  默认往下,测试框架有Qt Test、GTest、BoostTest、Catch2等常用主流单元测试框架,这里选Qt Test,GTest和Boost都需要安装对应的环境

2.2、框架生成的默认函数

void initTestCase();

void cleanupTestCase();

这两个是框架自动调用的,出此以外还有:

void init();

void cleanup();

test_case1函数是用户可自定义的测试函数

总结一下系统自动调用的函数:

void initTestCase(); //在第一个测试函数执行之前被调用的初始化函数

void cleanupTestCase(); //在最后一个测试函数执行完毕之后调用的清理操作

void init(); //每次执行测试函数之前调用的初始化函数

void cleanup(); //每次执行完测试函数之后调用的清理操作

需要注意的是:测试函数必须声明成槽函数,此类的槽函数会被主动调用执行

3、开始测试

3.1、测试一个DbConvert类

Github:https://github.com/judesmorning/DbConvert

主要有这么一个函数:

 

 3.2、将待测试的类集成到单元测试工程中

 

 注意.pro中也要添加进来

SOURCES += tst_mytest.cpp \

../converttool.cpp

HEADERS += \

../converttool.h

3.3、常规测试

创建单次测试的函数,主要用于验证Qt单元测试可用到的工具宏:

 

 实现:

void MyTest::test_qtest()

{

//计算运行时间,多次运行测量

#if 0

QBENCHMARK(m_tool->calc(QString("0"), ConvertTool::CalType_dBm2mW));

#endif

//计算运行时间,单次运行测量

#if 0

QBENCHMARK_ONCE(m_tool->calc(QString("0"), ConvertTool::CalType_dBm2mW));

#endif

//比较是否相等

#if 0

QCOMPARE(m_tool->calc(QString("0"), ConvertTool::CalType_dBm2mW), QString("1"));

#endif

//将下1个QCOMPARE或QVERIFY标记为预期测试,如果预期测试没有通过,可以终止剩余当前单元测试【可设置测试终止或继续】

//第1个参数为空只打印第2个参数,否则打印异常位置

//第1个参数为Continue、Abort,表示如果不通过是否继续执行剩余用例

#if 0

QEXPECT_FAIL("", "Will fix in the next release", Continue);

QCOMPARE(m_tool->calc(QString("0"), ConvertTool::CalType_dBm2mW), QString("10"));

#endif

//强制抛出错误并打印信息

#if 0

if (5 != 4)

{

QFAIL("This test has not been ported to this platform yet.");

}

#endif

//创建临时变量,从当前数据表中读取数据

#if 0

//在data函数中创建

QTest::addColumn("a");

QTest::addColumn("b");

QTest::newRow("positive value") << 100 << 100;

//在测试函数中取出

QFETCH(int, a);

QFETCH(int, b);

QCOMPARE(a, b);

#endif

//创建全局变量,从全局数据表中读取数据,必须有initTestCase_data

#if 0

//QFETCH_GLOBAL?

#endif

//从路径获取测试数据

#if 0

MyXmlParser parser;

QString input = QFINDTESTDATA("testxml/simple1.xml");

QVERIFY(parser.parse(input));

#endif

//停止测试,但不会将失败添加到失败日志

#if 0

if (4 != 5)

{

QSKIP("This test requires the SQLITE database driver");

}

#endif

//可替代QFETCH+QCOMPARE的便利写法,不需要QFETCH来生成变量

#if 0

QTEST(QString("hello").toUpper(), "myString");

#endif

//与QCOMPARE相似,但重复执行两个值的比较,直到两个值相等或者达到超时时间

#if 0

QTRY_COMPARE_WITH_TIMEOUT(1, 1, 5);

#endif

//执行QTRY_COMPARE_WITH_TIMEOUT,并将超时时间设置为5秒

#if 0

QTRY_COMPARE(1, 1);

#endif

//判断条件是否为true,如果为true则继续执行测试,否则记录失败日志并且不再执行单元测试

#if 0

QVERIFY(1+1==2);

#endif

//与QVERIFY相似,但可以自定义失败日志

#if 0

QVERIFY2(1+1==2, "A breach in basic arithmetic occurred.");

#endif

//与QVERIFY相似,但重复执行条件的判断,直到条件为true或者达到超时时间

#if 0

QTRY_VERIFY_WITH_TIMEOUT(1+1==2, 5);

#endif

//执行QTRY_VERIFY_WITH_TIMEOUT,并将超时时间设置为5秒

#if 0

QTRY_VERIFY(1+1==2);

#endif

//与QVERIFY2相似,但重复执行条件的判断,直到条件为true或者达到超时时间

#if 0

QTRY_VERIFY2_WITH_TIMEOUT(3>2, "this is log msg", 5);

#endif

//执行QTRY_VERIFY2_WITH_TIMEOUT,并将超时时间设置为5秒

#if 0

QTRY_VERIFY2(3>2, "this is log msg");

#endif

//执行表达式,并判断语句抛出的异常是否与预期异常相等

#if 0

//QVERIFY_EXCEPTION_THROWN

#endif

//主动添加警告日志,线程安全

#if 0

QWARN("msg");

#endif

}

3.4、数据驱动测试

创建一个函数test_calc,并将此函数名后加“_data”作为新的函数,再创建一个待测类指针:

 

①、

根据前面的说明,我们可以在initTestCase中new出指针,在cleanupTestCase中delete指针

void MyTest::initTestCase()

{

m_tool = new ConvertTool(nullptr);

}

void MyTest::cleanupTestCase()

{

delete m_tool;

m_tool = nullptr;

}

②、

void MyTest::test_calc_data()

{

/*创建测试参数*/

QTest::addColumn("calStr"); //创建第1个入参集合

QTest::addColumn("type"); //创建第2个入参集合

QTest::addColumn("result"); //创建返回值集合

/*设计用例*/

QTest::newRow("ok_1") << "0" << ConvertTool::CalType_dBm2mW << "1";

QTest::newRow("ok_2") << "10" << ConvertTool::CalType_dBm2mW << "10";

QTest::newRow("ng_1") << "10" << ConvertTool::CalType_dBm2mW << "100";

}

③、

void MyTest::test_calc()

{

//取出测试数据

QFETCH(QString, calStr);

QFETCH(ConvertTool::CalType, type);

QFETCH(QString, result);

//测试

QCOMPARE(m_tool->calc(calStr, type), result);

}

即test_calc函数会实例化test_calc_data中的测试用例并执行测试

 ④、

可直接运行程序,在应用程序输出里看结果

 

 为了直观,可在Test Results里运行程序,通过图形的形式展示

 

 在Test Results里,也可将测试结果输出到文档中:

 

 右键最上面的测试行,选择“save output to file",可将结果存成文档:

 

 

 

说明:

1.如果待测工程很大,建议在待测工程基础上增加一个pri和一个自动化测试的类,屏蔽main函数

 

精彩内容

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。