警告

本节包含从C++自动翻译到Python的代码片段,可能包含错误。

第2章:数据驱动测试#

如何创建数据驱动测试。

本章演示如何使用不同的测试数据多次执行测试。

到目前为止,我们已将想要测试的数据硬编码到我们的测试函数中。如果我们添加更多测试数据,函数可能看起来像这样

QCOMPARE(QString("hello").toUpper(), QString("HELLO"))
QCOMPARE(QString("Hello").toUpper(), QString("HELLO"))
QCOMPARE(QString("HellO").toUpper(), QString("HELLO"))
QCOMPARE(QString("HELLO").toUpper(), QString("HELLO"))

为了避免函数因重复代码而变得杂乱,Qt Test 支持向测试函数添加测试数据。我们只需向测试类添加另一个私有槽即可

class TestQString(QObject):

    Q_OBJECT
# private slots
    def toUpper_data():
    def toUpper():

编写数据函数#

与测试函数关联的数据函数名称中附加 _data。我们的数据函数看起来像这样

def toUpper_data(self):

    QTest.addColumn<QString>("string")
    QTest.addColumn<QString>("result")
    QTest.newRow("all-lower") << "hello" << "HELLO"
    QTest.newRow("mixed") << "Hello" << "HELLO"
    QTest.newRow("all-upper") << "HELLO" << "HELLO"

首先,我们使用 addColumn() 函数定义测试表的两个元素:一个测试字符串以及将 QString::toUpper() 函数应用到该字符串的预期结果。

然后,我们使用 newRow() 函数向表中添加一些数据。如果需要格式化行名称,例如在迭代生成许多数据行时,我们也可以使用 addRow()。每行数据将成为测试表中的一条单独的行。

newRow() 接受一个参数:一个将与数据集相关联并用于测试日志中识别数据行的名称。addRow() 接受一个(printf 风格)格式字符串,后跟要替换格式字符串中的格式标记的参数。然后,我们将数据集流到新表格行中。首先是一个任意的字符串,然后是将 QString::toUpper() 函数应用到该字符串的预期结果。

您可以将测试数据视为一个二维表。在我们的案例中,它有两个名为 stringresult 的列和三行。此外,每行都与一个名称和索引相关联

索引

名称

字符串

结果

0

全部小写

“hello”

HELLO

1

混合

“Hello”

HELLO

2

全部大写

“HELLO”

HELLO

当数据流入行时,每个数据应断言与它提供的列的值的类型相匹配。如果任何断言失败,测试将被终止。

在特定测试函数的数据表中,行和列的名称应该是唯一的:如果两行具有相同的名称,或者两列具有相同的名称,则(自Qt 6.5以来)将产生警告。有关如何将警告视为错误的信息,请参阅 测试警告;有关如何使测试摆脱其他警告的信息,请参阅如何清除测试警告。

重写测试函数#

现在我们可以重写我们的测试函数了

def toUpper(self):

    QFETCH(QString, string)
    QFETCH(QString, result)
    QCOMPARE(string.toUpper(), result)

TestQString::toUpper() 函数将被执行三次,每次针对我们在关联的 TestQString::toUpper_data() 函数中创建的测试表中的一条记录。

首先,我们使用 QFETCH() 宏获取数据集的两个元素。 QFETCH() 具有两个参数:元素的类型和元素的名称。然后,我们使用 QCOMPARE() 宏进行测试。

这种方法使得在不修改测试本身的情况下轻松添加新的数据到测试中变得非常容易。

准备独立的可执行文件#

同样地,为了使我们的测试用例成为一个独立的可执行文件,需要以下两行:

QTEST_MAIN(TestQString)
from testqstring.moc import *

和之前一样,QTEST_MAIN() 宏扩展为一个简单的 main() 方法,它运行所有的测试函数。由于我们的测试类的声明和实现都在一个 .cpp 文件中,我们还需要包含生成的 moc 文件以使 Qt 的反射功能工作。

构建可执行文件#

您可以使用 CMake 或 qmake 构建测试用例的可执行文件。

使用 CMake 构建#

在您的 CMakeLists.txt 文件中配置您的构建设置

<Code snippet "/data/qt5-full-670/6.7.0/Src/qtbase/tutorial2/CMakeLists.txt" not found>

接下来,从命令行运行 cmake 或使用位于 Qt-prefix/<version>/<platform>/bin/qt-cmake 的便利脚本 qt-cmake

<Qt-prefix>/<version>/<platform>/bin/qt-cmake <source-dir> <build-dir> -G Ninja

然后,运行您首选的生成工具来构建可执行文件。这里我们使用 Ninja

ninja

使用 qmake 构建#

在您的 .pro 文件中配置您的构建设置

<Code snippet "/data/qt5-full-670/6.7.0/Src/qtbase/tutorial2/tutorial2.pro" not found>

接下来,运行 qmake,然后最终运行 make 来构建您的可执行文件

qmake
make

运行可执行文件#

运行生成的可执行文件应该会给出以下输出

********* Start testing of TestQString *********
Config: Using QtTest library %VERSION%, Qt %VERSION%
PASS   : TestQString::initTestCase()
PASS   : TestQString::toUpper(all-lower)
PASS   : TestQString::toUpper(mixed)
PASS   : TestQString::toUpper(all-upper)
PASS   : TestQString::cleanupTestCase()
Totals: 5 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
********* Finished testing of TestQString *********