4. 自动化测试基础
在嵌入式UI项目中,自动化测试并不是“写几个脚本跑一跑”这么简单。它需要一套分层策略:哪些逻辑用单元测试快速验证,哪些接口用集成测试保证协作正确,哪些场景必须放到系统测试或UI测试中验证。理解测试金字塔,是建立可持续测试体系的第一步。
一、测试金字塔:分层投入与反馈速度
测试金字塔由Mike Cohn提出,核心思想是:底层测试数量多、执行快、成本低;上层测试数量少、执行慢、成本高。对于嵌入式UI,底层通常是纯逻辑与协议解析,中层是模块间接口与驱动交互,顶层是整机行为与UI操作。
金字塔不是“必须严格按比例”,而是提醒我们:如果UI测试数量远超单元测试,测试套件会变得又慢又脆。嵌入式UI常见的反模式是“所有验证都靠上电后点屏幕”,结果每次回归要几十分钟,失败原因还难以定位。
二、五类测试的区别与联系
单元测试针对最小可测单元,通常是纯函数、状态机、协议编解码、UI数据绑定逻辑。它不依赖真实硬件,用桩或模拟替代外部依赖,执行时间在毫秒级。集成测试验证两个或多个模块组合后的行为,例如触摸驱动与事件分发、显示驱动与帧缓冲、通信协议与业务解析。系统测试从整机角度验证功能与非功能需求,如开机流程、页面切换、告警响应、低功耗唤醒。UI测试则模拟用户操作,验证控件布局、触摸响应、动画与多语言显示。
| 测试类型 | 验证对象 | 典型工具/手段 | 执行速度 | 失败定位难度 |
|---|---|---|---|---|
| 单元测试 | 函数、状态机、解析逻辑 | Unity、GoogleTest、pytest | 毫秒级 | 低 |
| 集成测试 | 模块接口、驱动与中间件 | Mock驱动、仿真器、桩函数 | 秒级 | 中 |
| 系统测试 | 整机功能、性能、功耗 | 硬件在环、自动化脚本 | 分钟级 | 较高 |
| UI测试 | 控件、触摸、视觉呈现 | Appium、SikuliX、LVGL模拟器 | 分钟级 | 高 |
它们的联系在于“同一需求在不同层次被反复验证”。例如“点击按钮后LED亮起”:单元测试验证按钮事件处理函数返回正确状态;集成测试验证GPIO驱动被正确调用;系统测试验证真实LED亮起;UI测试验证按钮可点击且无遮挡。层次越往上,越接近用户价值,但反馈越慢、维护成本越高。
三、TDD简介:先写测试,再写实现
测试驱动开发(TDD)的核心循环是“红—绿—重构”:先写一个失败的测试(红),再写最少代码让测试通过(绿),最后在测试保护下重构。对嵌入式UI而言,TDD特别适合纯逻辑层,例如页面状态机、菜单导航、数据格式化、协议解析。
// 示例:LVGL页面状态机TDD片段(伪代码)
TEST(PageState, switch_to_settings_when_click_settings) {
page_state_init();
page_state_handle_event(EVENT_CLICK_SETTINGS);
ASSERT_EQ(page_state_current(), PAGE_SETTINGS);
}
// 先运行:失败(红)
// 实现page_state_handle_event后:通过(绿)
// 再重构事件表,测试仍通过
四、案例与误区复盘
某智能面板项目初期只做UI自动化,每次回归需25分钟,且经常因动画时序失败。后来团队将协议解析、页面状态机下沉为单元测试,把驱动交互改为集成测试,UI测试只保留8条核心路径。结果回归时间降到6分钟,失败定位从“看截图猜”变成“直接看断言”。
建议的实践顺序是:先为纯逻辑建立单元测试,再为关键接口建立集成测试,然后用系统测试覆盖开机、通信、告警等端到端场景,最后用少量UI测试守住用户可见的关键路径。每一层都应有明确的通过标准和失败回滚策略,并与CI流水线绑定,让测试金字塔真正支撑嵌入式UI的持续集成。