欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Qt测试框架概述

程序员文章站 2024-03-16 18:42:22
...

Qt测试框架概述

Qt 5.10.1

Qt Test是一个基于Qt的应用程序和库的单元测试框架。 Qt Test提供了单元测试框架中常见的所有功能,以及用于测试图形用户界面的扩展。

Qt Test旨在简化基于Qt的应用程序和库的单元测试的编写:

Feature Details
Lightweight Qt Test包含大约6000行代码和60个导出符号。
Self-contained Qt Test只需要Qt Core模块中的几个符号进行非gui测试。
Rapid testing Qt测试不需要特殊的测试runner; 没有专门的测试注册。
Data-driven testing 可以使用不同的测试数据多次执行测试。
Basic GUI testing Qt Test提供鼠标和键盘模拟功能。
Benchmarking Qt Test支持基准测试并提供多个测量后端。
IDE friendly Qt Test输出可由Visual Studio和KDevelop解释的消息。
Thread-safety 错误报告是线程安全和原子的。
Type-safety 广泛使用模板可防止隐式类型转换引入的错误。
Easily extendable 可以轻松地将自定义类型添加到测试数据和测试输出中。

创建测试

要创建测试,请将QObject子类化并向其添加一个或多个专用槽。 每个专用插槽都是测试中的测试功能。QTest::qExec()可用于执行测试对象中的所有测试功能。
此外,有四个私有插槽不被视为测试功能。 它们将由测试框架执行,可用于初始化和清理整个测试或当前测试功能。

  • 在执行第一个测试函数之前将调用initTestCase()
  • 执行最后一个测试函数后,将调用cleanupTestCase()
  • 在执行每个测试函数之前将调用init()
  • 每个测试函数后都会调用cleanup()

如果initTestCase()失败,则不会执行测试功能。 如果init()失败,则不会执行以下测试函数,测试将进入下一个测试函数。
例:

class MyFirstTest: public QObject
{
      Q_OBJECT
  private slots:
      void initTestCase()
      { qDebug("called before everything else"); }
      void myFirstTest()
      { QVERIFY(1 == 1); }
      void mySecondTest()
      { QVERIFY(1 != 2); }
      void cleanupTestCase()
      { qDebug("called after myFirstTest and mySecondTest"); }
};

有关更多示例,请参阅Qt测试教程。

建立一个测试

如果您使用qmake作为构建工具,只需将以下内容添加到项目文件中:

QT + = testlib

如果您想通过make check运行测试,请添加其他行:

CONFIG + = testcase

有关make check的更多信息,请参阅qmake手册
如果您正在使用其他构建工具,请确保将Qt Test头文件的位置添加到包含路径(通常在Qt安装目录下include/QtTest)。 如果您使用的是Qt的发布版本,请将测试链接到QtTest库。 对于调试版本,请使用QtTest_debug。
请参阅编写单元测试以获得分步说明。

Qt测试命令行参数

语法

执行自动测试的语法采用以下简单形式:

testname [options] [testfunctions[:testdata]]...

用您的可执行文件的名称替换testname。 testfunctions可以包含要执行的测试函数的名称。 如果没有通过测试功能,则运行所有测试。 如果在testdata中附加条目的名称,则测试函数将仅与该测试数据一起运行。
例如:

/myTestDirectory$ testQString toUpper

使用所有可用的测试数据运行名为toUpper的测试函数。

/myTestDirectory$ testQString toUpper toInt:zero

使用所有可用的测试数据运行toUpper测试函数,并使用名为零的测试数据运行toInt测试函数(如果指定的测试数据不存在,则关联的测试将失败)。

/myTestDirectory$ testMyWidget -vs -eventdelay 500

运行testMyWidget功能测试,输出每个信号发射,并在每次模拟鼠标/键盘事件后等待500毫秒。

选项

记录选项

以下命令行选项确定如何报告测试结果:

  • -o filename,格式
    以指定的格式(txt,xml,lightxml或xunitxml之一)将输出写入指定的文件。特殊文件名 - 可用于登录标准输出。
  • -o filename
    将输出写入指定的文件。
  • -txt
    输出结果为纯文本。
  • -xml
    将结果输出为XML文档。
  • -lightxml
    输出结果作为XML标记流。
  • -xunitxml
    输出结果作为Xunit XML文档。
  • -csv
    以逗号分隔值(CSV)输出结果。此模式仅适用于基准测试,因为它抑制了正常的通过/失败消息。
  • -teamcity
    输出结果为TeamCity格式。

可以重复-o选项的第一个版本,以便以多种格式记录测试结果,但是此选项的不超过一个实例可以将测试结果记录到标准输出。

如果使用-o选项的第一个版本,则不应使用-o选项的第二个版本,也不应使用-txt,-xml,-lightxml,-teamcity或-xunitxml选项。

如果未使用-o选项的任何版本,则测试结果将记录到标准输出。如果未使用格式选项,则测试结果将以纯文本格式记录。

测试日志详细选项

以下命令行选项控制测试日志中报告的详细信息量:

  • -silent
    静默输出;仅显示致命错误,测试失败和最小状态消息。
  • -V1
    详细输出;显示输入每个测试功能的时间。 (此选项仅影响纯文本输出。)
  • -V2
    扩展的详细输出;显示每个QCOMPARE()和QVERIFY()。 (此选项会影响所有输出格式,并暗示-v1表示纯文本输出。)
  • -vs
    显示发出的所有信号以及由这些信号产生的插槽调用。 (此选项会影响所有输出格式。)

测试选项

以下命令行选项会影响测试的运行方式:

  • -functions
    输出测试中可用的所有测试功能,然后退出。
  • -datatags
    输出测试中可用的所有数据标签。全局数据标记前面有__global__
  • -eventdelay ms
    如果没有为键盘或鼠标模拟指定延迟(QTest::keyClick()QTest::mouseClick()等),则替换此参数中的值(以毫秒为单位)。
  • -keydelay ms
    像-eventdelay,但只影响键盘模拟,而不影响鼠标模拟。
  • -mousedelay ms
    像-eventdelay,但只影响鼠标模拟,而不影响键盘模拟。
  • -maxwarnings number
    设置要输出的最大警告数。 0表示无限制,默认为2000。
  • -nocrashhandler
    在Unix平台上禁用崩溃处理程序。在Windows上,它会重新启用Windows错误报告对话框,该对话框默认情况下处于关闭状态。这对于调试崩溃非常有用。
  • -platform name
    此命令行参数适用于所有Qt应用程序,但在自动测试的上下文中可能特别有用。通过使用“offscreen”平台插件(-platform offscreen),可以使用QWidget或QWindow运行的测试,而不会在屏幕上显示任何内容。目前,只有X11完全支持屏外平台插件。

基准选项

以下命令行选项控制基准测试:

  • -callgrind
    使用Callgrind计时基准(仅限Linux)。
  • -tickcounter
    使用CPU tick计数器计时基准。
  • -eventcounter
    计算基准期间收到的事件。
  • -minimumvalue n
    设置可接受的最小测量值。
  • -minimumtotal n
    设置重复执行测试函数的最小可接受总数。
  • -iterations n
    设置累积迭代次数。
  • -median n
    设置中值迭代次数。
  • -vb
    输出详细的基准信息。

其他选项

  • -help
    输出可能的命令行参数并提供一些有用的帮助。

创建基准

要创建基准测试,请按照创建测试的说明进行操作,然后将QBENCHMARK宏添加到要进行基准测试的测试功能中。

class MyFirstBenchmark: public QObject
{
    Q_OBJECT
private slots:
    void myFirstBenchmark()
    {
        QString string1;
        QString string2;
        QBENCHMARK {
            string1.localeAwareCompare(string2);
        }
    }
};

QBENCHMARK宏中的代码将被测量,并且可能也会重复几次以获得准确的测量结果。 这取决于所选的测量后端。 有几个后端可供使用。 可以在命令行中选择它们:

Name Command-line Argument Availability
Walltime (default) All platforms
CPU tick counter -tickcounter Windows, macOS, Linux, many UNIX-like systems.
Event Counter -eventcounter All platforms
Valgrind Callgrind -callgrind Linux (if installed)
Linux Perf -perf Linux

简而言之,Walltime始终可用,但需要多次重复才能获得有用的结果。 Tick计数器通常是可用的,可以提供更少重复的结果,但可能容易受到CPU频率调整问题的影响。 Valgrind提供精确的结果,但不考虑I/O等待,并且仅在有限数量的平台上可用。事件计数在所有平台上都可用,它提供事件循环在发送到相应目标之前接收的事件数(这可能包括非Qt事件)。

Linux性能监控解决方案仅在Linux上可用,并提供许多不同的计数器,可以通过传递额外的选项-perfcounter
countername来选择,例如-perfcounter cache-misses-perfcounter branch-misses-perfcounter l1d-load-misses。默认计数器是cpu-cycles。可以通过使用选项-perfcounterlist运行任何基准可执行文件来获取计数器的完整列表。

  • 笔记:
    • 使用性能计数器可能需要启用对非特权应用程序的访问。
    • 不支持高分辨率计时器的设备默认为1毫秒粒度。

有关更多基准测试示例,请参阅Qt测试教程中的编写基准。