一、工程准备

QTestLib框架提供了一个简单易用的单元测试框架,创建工程如下:

Qt单元测试框架_测试类


Qt单元测试框架_单元测试_02


Qt单元测试框架_测试类_03

  • Requires QApplication选项为程序添加QApplication类;
  • Generate initialization and cleanup code选项为添加初始化与清除代码(函数);

Qt单元测试框架_单元测试_04


Qt单元测试框架_开发语言_05


二、使用说明

新建的测试工程如下:

Qt单元测试框架_测试类_06


注意事项

  • 每一个测试类中的每一项测试条目必须在Qt槽中(private slots),否则无法调用;
  • 单元测试不具有main函数,测试条目会顺序执行;
  • ​initTestCase()​​会在第一个测试函数执行前调用(系统自带);
  • ​cleanupTestCase()​​会在最后一个测试函数执行后调用(系统自带);
  • ​init()​​会在每一个测试函数执行前调用;
  • ​cleanup()​​会在每一个测试函数执行后调用;
  • 使用​​QVERIFY(para)​​:验证参数是否为真;
  • 使用​​QCOMPARE(actual, expected)​​:验证实际参数是否跟期望值一致;

三、高级操作

1、输出测试报告

打开cmd,切换到可执行文件所在目录(.exe文件所在目录),输入:​​xxx -xml -vs -lightxml -o OutFile.txt​​,即可将测试结果保存到OutFile.txt文件中(xxx是测试项目对应的可执行文件名);

Qt单元测试框架_sed_07


Qt单元测试框架_单元测试_08

2、GUI测试

Qtestlib单元测试提供GUI操作函数,可对控件发送消息后检测执行结果,比如QTest::keyClick(),QTest::mouseClick()等等,详情请见​​参考文档​

下面提供鼠标操作相关的枚举类型:

Constant

Value

Description

QTest::MousePress

0

A mouse button is pressed.

QTest::MouseRelease

1

A mouse button is released.

QTest::MouseClick

2

A mouse button is clicked (pressed and released).

QTest::MouseDClick

3

A mouse button is double clicked (pressed and released twice).

QTest::MouseMove

4

The mouse pointer has moved.

下面为鼠标相关的操作函数:

void mouseClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay = -1)
void mouseClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay = -1)
void mouseDClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay = -1)
void mouseDClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay = -1)
void mouseMove(QWidget *widget, QPoint pos = QPoint(), int delay = -1)
void mouseMove(QWindow *window, QPoint pos = QPoint(), int delay = -1)
void mousePress(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay = -1)
void mousePress(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay = -1)
void mouseRelease(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay = -1)
void mouseRelease(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), QPoint pos = QPoint(), int delay = -1)

3、结果可视化-AutoTest插件

默认测试结果显示在控制台(应用程序输出标签)以纯文本形式显示,不够直观,可使用AutoTest插件实现可视化效果

通过帮助-关于插件-AutoTest开启即可,启动此插件需要重启Qt Creator,然后再下方会多出TestResults的标签,可直接在此标签点击上方的运行按钮运行所有测试,同时在“工具-Test”也可运行所有测试

Qt单元测试框架_单元测试_09

Qt单元测试框架_测试类_10


此插件可以在运行单元测试后以红、绿色表示明确标记处运行结果,并且以Case为单位显示,可以展开看到具体每一个测试用例的结果。

4、可以用到的测试宏命令

QBENCHMARK
QBENCHMARK_ONCE
QCOMPARE(actual, expected)
QEXPECT_FAIL(dataIndex, comment, mode)
QFAIL(message)
QFETCH(type, name)
QFINDTESTDATA(filename)
QSKIP(description)
QTEST(actual, testElement)
QTEST_APPLESS_MAIN(TestClass)
QTEST_GUILESS_MAIN(TestClass)
QTEST_MAIN(TestClass)
QTRY_COMPARE(actual, expected)
QTRY_COMPARE_WITH_TIMEOUT(actual, expected, timeout)
QTRY_VERIFY2(condition, message)
QTRY_VERIFY(condition)
QTRY_VERIFY2_WITH_TIMEOUT(condition, message, timeout)
QTRY_VERIFY_WITH_TIMEOUT(condition, timeout)
QVERIFY2(condition, message)
QVERIFY(condition)
QVERIFY_EXCEPTION_THROWN(expression, exceptiontype)
QWARN(message)

5、单元测试注意事项

  • 单元测试类中建议不要出现私有成员,尤其是指针,同时不建议在测试函数中建立被测类的指针,而是直接建立被测类的对象,在测试结束后容易遗忘指针。若需要指针initTestCase中new,在cleanupTestCase中delete。
  • 若某个测试函数中出现了new,一定记着delete,且务必让delete在第一个断言前出现,因为断言失败函数就回立刻结束,并把当前函数标记为测试失败。若delete在第一个断言之后,而第一个断言失败则不会执行之后的delete。
  • 若测试类必须有私有成员,必须注意一个测试类中的所有函数公用私有成员,不会在每个测试之前刷新状态。

6、被测类为单例时
若被测类为单例,欲对其内所有函数做单元测试,会出现测试第一个函数可以保证测试环境为初始状态,后续测试回因为单例的原因,导致测试时建立在之前操作后的环境下。欲解决此问题,需要删除单例。