Qt Quick Test模块功能及架构
Qt Quick Test 是专门为测试 QML 应用程序设计的模块,在 Qt 6.0 中得到了显著增强。
一、主要功能/使用方法
核心功能概述
-
QML 单元测试框架
-
提供完整的 QML 测试环境
-
支持测试用例组织和执行
-
包含 QML 断言函数和测试结果收集
-
-
测试类型支持
-
组件功能测试
-
用户界面行为测试
-
信号和属性绑定测试
-
可视化项渲染测试
-
基本使用方法
1. 创建测试文件
// tst_example.qml
import QtQuick 2.15
import QtTest 1.15TestCase {name: "ExampleTests"function test_math() {compare(1 + 1, 2, "Basic math")}function test_property() {var obj = createTemporaryObject(component, parent)verify(obj !== null, "Object created")compare(obj.width, 100, "Default width")}
}
2. 主测试文件
// tst_main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtTest 1.15Window {visible: truewidth: 400height: 300TestCase {id: mainTestname: "MainTests"when: windowShownfunction test_window() {compare(window.width, 400, "Window width")compare(window.height, 300, "Window height")}}
}
关键测试元素
-
TestCase
-
基础测试容器
-
提供测试函数和断言方法
-
支持异步测试
-
-
SignalSpy
-
监听信号发射
-
记录信号发射次数和参数
-
-
TestEvent
-
模拟鼠标和键盘输入
-
支持触摸事件模拟
-
主要断言方法
方法 | 描述 |
---|---|
compare(actual, expected, message) | 比较实际值和期望值 |
verify(condition, message) | 验证条件为真 |
tryCompare(obj, prop, expected, timeout, message) | 异步比较属性值 |
fail(message) | 强制测试失败 |
skip(message) | 跳过当前测试 |
高级功能
1. 异步测试
function test_async() {var obj = createTemporaryObject(component, parent)obj.signal.connect(function() {// 信号处理})tryCompare(obj, "status", "ready", 1000, "Object should become ready")
}
2. 信号监测
function test_signal() {var obj = createTemporaryObject(component, parent)var spy = createTemporaryObject(signalSpyComponent, null, {target: obj, signalName: "clicked"})mouseClick(obj)compare(spy.count, 1, "Signal should be emitted once")
}
3. 事件模拟
function test_events() {var obj = createTemporaryObject(buttonComponent, parent)mouseClick(obj, 10, 10, Qt.LeftButton)keyClick(Qt.Key_Enter)
}
Qt 6.0 新特性
-
改进的组件创建
-
createTemporaryObject()
更可靠 -
更好的内存管理
-
-
增强的事件模拟
-
支持多点触控
-
更精确的鼠标移动模拟
-
-
更好的调试支持
-
详细的错误信息
-
测试失败时的堆栈跟踪
-
-
与 C++ 测试集成
-
可以在 C++ 测试中嵌入 QML 测试
-
共享测试基础设施
-
测试执行
-
命令行执行
qmltestrunner -input tst_example.qml
-
输出选项
-
-o file,xml
XML 格式输出 -
-o file,txt
文本格式输出 -
-o file,lightxml
轻量级 XML 输出
-
-
测试选择
-
按名称筛选测试用例
-
支持通配符匹配
-
最佳实践
-
测试组织
-
按功能模块分组测试
-
使用有意义的测试名称
-
-
测试数据
-
使用 JSON 文件存储测试数据
-
考虑使用数据驱动测试
-
-
测试稳定性
-
避免依赖绝对时间
-
使用
tryCompare
处理异步操作
-
-
CI/CD 集成
-
生成 JUnit 格式报告
-
与 CMake 测试集成
-
二、架构解析
整体架构层次
1. QML 测试接口层
-
测试用例声明:通过
TestCase
QML 类型定义测试 -
断言系统:提供
compare()
,verify()
等 QML 可调用方法 -
测试控制:管理测试执行顺序和生命周期
2. C++ 核心引擎层
-
测试运行器:
QQmlTestRunner
类负责调度测试执行 -
QML 引擎集成:与
QQmlEngine
深度集成,支持组件实例化 -
事件系统:
QQuickTestEvent
及相关类处理输入模拟
3. 底层适配层
-
与 Qt Test 集成:共享基础测试设施和报告系统
-
平台抽象:处理不同平台的输入事件差异
核心组件设计
1. TestCase 类型系统
TestCase {// 测试元数据name: "MyTests"when: windowShown// 测试资源管理function initTestCase() {}function cleanupTestCase() {}// 测试函数function test_example() {compare(1+1, 2)}
}
2. 测试执行流程
-
解析阶段:加载 QML 测试文件,识别测试用例
-
初始化阶段:调用
initTestCase()
-
执行阶段:按顺序运行测试函数
-
清理阶段:调用
cleanupTestCase()
-
报告阶段:生成测试结果输出
3. 关键类关系
QQmlTestRunner
├── QQmlEngine
├── QQuickTestCase
│ ├── QQuickTestEvent
│ └── QQuickTestResult
└── QTestLogger
三、事件系统架构
1. 输入事件模拟
-
鼠标事件:
mouseClick()
,mouseMove()
-
键盘事件:
keyClick()
,keyPress()
-
触摸事件:
touchEvent()
2. 事件处理流程
测试代码调用事件方法
→ QQuickTestEvent 创建平台事件
→ QQuickWindow 事件分发
→ 目标 Item 处理事件
→ 测试验证结果
信号监测系统
1. SignalSpy 实现
SignalSpy {target: testObjectsignalName: "statusChanged"
}
2. 工作原理
-
使用 Qt 元对象系统动态连接信号
-
通过槽函数记录信号触发信息
-
提供
count
和signalArguments
属性
Qt 6.0 架构改进
-
QML 引擎优化
-
更快的组件实例化 (
createTemporaryObject
) -
改进的垃圾回收策略
-
-
测试隔离增强
-
每个测试用例在独立上下文中运行
-
更好的资源清理机制
-
-
异步测试改进
-
更精确的
tryCompare
超时控制 -
支持 Promise 风格的异步测试
-
-
调试支持
-
增强的错误位置报告
-
与 Qt Creator 深度集成
-
执行模型
1. 测试发现
-
扫描指定目录的
tst_*.qml
文件 -
解析 TestCase 元素及其测试函数
2. 执行模式
-
顺序执行:默认串行执行测试
-
过滤执行:支持通过名称筛选测试
-
GUI 模式:需要显示窗口的测试 (
when: windowShown
)
报告系统
1. 输出格式支持
-
TAP (Test Anything Protocol)
-
XML (xUnit 风格)
-
文本 (人类可读)
-
LightXML (简化 XML)
2. 报告生成流程
测试执行
→ QQuickTestResult 收集结果
→ QTestLogger 格式化输出
→ 控制台/文件输出
扩展机制
1. 自定义断言
function assertApproxEqual(actual, expected, tol) {if (Math.abs(actual - expected) > tol)fail("Values differ by more than " + tol)
}
2. 测试工具组件
-
可创建可复用的测试组件
-
支持通过 QML 组件注入测试依赖
性能优化
-
延迟初始化:按需创建测试对象
-
智能重绘:最小化不必要的界面更新
-
并行化准备:预编译测试 QML 文件
Qt Quick Test 的这种架构设计使其能够高效地测试 Qt Quick 应用程序,同时保持 QML 开发的自然工作流程,是 Qt 6.0 中 UI 测试的重要基础设施。