跳到主要内容

编写测试

为 ElenixOS 新增测试时,首先需要判断验证需求应走框架层管道还是构建独立的 GUI 页面。两条路径服务于不同的验证目标,在运行方式、结果判定和集成方式上各有侧重。理解二者的适用场景及框架层的内部流程,是保证测试一致性和可维护性的前提。

选择执行路径

纳入框架层管道适用于对子系统 API 的逻辑正确性验证、需要批量执行和统一统计的场景、可能被反复执行的回归用例,以及边界条件和错误路径的参数化验证。其优势在于自动化执行和统一的通过/失败聚合;代价是测试函数必须为同步形态且返回值有明确语义。

构建独立 GUI 页面适用于需要人工观察 UI 渲染效果的验证、依赖持续交互(滑动、按键、拖拽)的场景、实时传感器数据可视化的展示,以及音频播放/录制等依赖硬件反馈的功能验证。其优势在于支持交互式操作和可视化反馈;代价是无法自动判定通过/失败,不适合批量回归。

两者在代码层面通过统一入口收敛:主测试菜单同时列出框架层的单元测试入口和各项独立页面入口,导航结构一致。

框架层测试

执行契约

框架层对测试函数的调用遵循一个隐含契约:测试函数在 LVGL 主循环线程中同步调用,返回前必须完成全部验证逻辑并记录结果。返回值 true 通常表示测试通过,但框架层以显式的结果记录调用为准判定通过/失败状态,返回值主要影响调用方的快速判断。因此测试函数内不应执行阻塞等待、不应依赖跨帧状态变更,也不应假设其他测试的执行顺序。

命名规范

测试名使用 前缀: 描述 格式。前缀建议使用子系统或子模块名,描述部分使用简洁的自然语言。框架层在构建 GUI 清单时自动按前缀聚合分组——拥有相同前缀的测试被归入同一分组并生成组级 UI。这意味着新增测试时只需保证前缀与现有同组测试一致即可自动归入正确分组,无需额外配置。

需要注意的是前缀粒度:过细会导致分组过多,影响 GUI 清单可用性;过粗会混合无关测试,降低选择精度。

断言宏

框架层提供的断言宏在单次调用中同时完成条件判断和结果记录,减少测试函数内部的样板代码。宏以参数中的条件表达式值作为通过/失败依据,将人可读描述作为详情字符串一并记录,使得单行断言即可表达完整的验证意图。

断言宏通过测试名查找框架层内部的对应条目并更新状态。这意味着断言宏严格依赖测试已在框架层注册这一前提——未注册的测试名在调用断言宏时仅产生日志警告,不会计入通过/失败统计。

处理异步场景

对于需要多轮 LVGL tick 或等待服务状态变更的异步测试场景,当前采用定时器驱动的状态机模式:测试函数在首次调用时注册通过(表明测试已启动),启动一个 LVGL 定时器驱动后续阶段,在最终阶段通过结果记录函数更新测试结果。

这种方式在同步调用-返回模型中植入了延迟结算点,利用了框架层允许后续覆盖结果记录的特性。需要注意覆盖行为仅限于尚未运行的测试——已被执行器标记为已运行的测试,后续的结果记录调用不会更新其状态,以避免重复计数。

编写注意事项

  • 测试名必须唯一。框架层注册时静默丢弃重名条目,不同子系统之间应通过前缀保证命名不冲突。
  • 注册必须在页面启动前完成。框架层 GUI 页面在入口函数中遍历已注册测试并构建 UI,页面启动后的注册不会反映到已创建的清单中。
  • 独立 GUI 页面不与框架层互通。在独立页面中手动记录的通过/失败统计不纳入框架层的聚合结果。
  • 容量上限。注册的测试数量和分组数量存在编译期上限,接近时应考虑合并。

接入流程

为现有子系统新增框架层测试:在子系统的测试模块中定义测试函数并遵循命名约定,在子系统的注册函数中注册测试,重新编译后新测试自动出现在 GUI 清单的对应分组中。

为 UI 组件或硬件交互新增交互式验证页面:创建基于 Activity 模型的新页面,在生命周期回调中管理 UI 的创建与清理,在主测试菜单中新增入口按钮绑定到页面启动回调。

为新开发的子系统创建完整测试模块:为子系统创建独立的测试文件,包含注册函数;在 runner 模块的聚合函数中插入对新注册函数的调用;所有测试文件通过 EOS_ENABLE_TEST_APP 进行条件编译保护。

待完善

待完善

该部分内容正在构建中,请稍后查看。

  • 异步测试的标准化:将定时器驱动的异步模式抽象为框架层的内置能力,使异步测试的定义与同步测试同样简洁
  • 测试数据分离:允许测试所需的输入数据以外部文件形式提供,与测试逻辑分离