第 4 章:重播 GUI 事件

在本章中,我们将展示如何模拟图形用户界面事件,以及如何存储一系列图形用户界面事件并在部件上重放这些事件。

存储一系列事件并重播它们的方法与第 2 章中介绍的方法十分相似。您只需在测试类中添加一个数据函数即可:

class TestGui: public QObject
{
    Q_OBJECT

private slots:
    void testGui_data();
    void testGui();
};

编写数据函数

与之前一样,测试函数的相关数据函数使用相同的名称,并附加_data

void TestGui::testGui_data()
{
    QTest::addColumn<QTestEventList>("events");
    QTest::addColumn<QString>("expected");

    QTestEventList list1;
    list1.addKeyClick('a');
    QTest::newRow("char") << list1 << "a";

    QTestEventList list2;
    list2.addKeyClick('a');
    list2.addKeyClick(Qt::Key_Backspace);
    QTest::newRow("there+back-again") << list2 << "";
}

首先,我们使用QTest::addColumn() 函数定义表格元素:GUI 事件列表,以及在QWidget 上应用事件列表的预期结果。请注意,第一个元素的类型是QTestEventList

QTestEventList 可填充 GUI 事件,这些事件可存储为测试数据以供日后使用,或在任何QWidget 上重放。

在当前的数据函数中,我们创建了两个QTestEventList 元素。第一个列表包含单击 "a "键的事件。我们使用QTestEventList::addKeyClick() 函数将事件添加到列表中。然后,我们使用QTest::newRow() 函数为数据集命名,并将事件列表和预期结果导入表格。

第二个列表由两个按键组成:一个 "a "和一个 "backspace"。我们再次使用QTestEventList::addKeyClick() 将事件添加到列表中,并使用QTest::newRow() 将事件列表和预期结果放入带有相关名称的表中。

重写测试函数

现在我们可以重写测试了:

void TestGui::testGui()
{
    QFETCH(QTestEventList, events);
    QFETCH(QString, expected);

    QLineEdit lineEdit;

    events.simulate(&lineEdit);

    QCOMPARE(lineEdit.text(), expected);
}

TestGui::testGui() 函数将执行两次,我们在相关 TestGui::testGui_data() 函数中创建的测试数据中的每个条目都将执行一次。

首先,我们使用QFETCH() 宏获取数据集中的两个元素。QFETCH() 包含两个参数:元素的数据类型和元素名称。然后,我们创建一个QLineEdit ,并使用QTestEventList::simulate() 函数将事件列表应用到该 widget 上。

最后,我们使用QCOMPARE() 宏检查行编辑的文本是否符合预期。

准备单机版可执行文件

与之前一样,要使我们的测试用例成为独立可执行文件,需要以下两行:

QTEST_MAIN(TestGui)
#include "testgui.moc"

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

构建可执行文件

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

使用 CMake 构建

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

# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

cmake_minimum_required(VERSION 3.16)
project(tutorial4 LANGUAGES CXX)

find_package(Qt6 REQUIRED COMPONENTS Core Gui Test Widgets)

qt_standard_project_setup()

qt_add_executable(tutorial4
    testgui.cpp
)

set_target_properties(tutorial4 PROPERTIES
    WIN32_EXECUTABLE TRUE
    MACOSX_BUNDLE TRUE
)

target_link_libraries(tutorial4 PRIVATE
    Qt6::Core
    Qt6::Gui
    Qt6::Test
    Qt6::Widgets
)

install(TARGETS tutorial4
    BUNDLE  DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

qt_generate_deploy_app_script(
    TARGET tutorial4
    OUTPUT_SCRIPT deploy_script
    NO_UNSUPPORTED_PLATFORM_ERROR
)
install(SCRIPT ${deploy_script})

然后,从命令行运行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 文件中配置编译设置:

QT += widgets testlib

SOURCES = testgui.cpp

# install
target.path = $$[QT_INSTALL_EXAMPLES]/qtestlib/tutorial4
INSTALLS += target

然后,运行qmake ,最后运行make 来构建可执行文件:

qmake
make

运行可执行文件

运行生成的可执行文件会有如下输出:

********* Start testing of TestGui *********
Config: Using QtTest library %VERSION%, Qt %VERSION%
PASS   : TestGui::initTestCase()
PASS   : TestGui::testGui(char)
PASS   : TestGui::testGui(there+back-again)
PASS   : TestGui::cleanupTestCase()
Totals: 4 passed, 0 failed, 0 skipped, 0 blacklisted, 18ms
********* Finished testing of TestGui *********

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.