第二章 测试框架选型:主流框架对比与选型决策矩阵

做嵌入式固件测试,选框架是个绕不开的坎。我见过不少团队,代码写得挺漂亮,一到测试就抓瞎——要么框架太重跑不动,要么太轻啥也测不了。今天咱们就把市面上几个主流框架掰开揉碎,看看它们到底适合什么场景。

2.1 四大框架速览

目前嵌入式圈子里,Unity、CMock、Ceedling 和 PyTest 的嵌入式扩展是出镜率最高的。我个人的习惯是:先看项目规模,再选框架。小项目用 Unity 就够了,大项目得上 Ceedling 全家桶。

2.1.1 Unity —— 轻量级单元测试框架

Unity 是纯 C 写的,核心就几个文件。你想想看,一个跑在单片机上的测试框架,能有多重?它连标准库都不依赖,非常适合资源受限的环境。

核心特点:

  • 纯 C 实现,无外部依赖
  • 支持断言、测试组、测试夹具
  • 可移植性极强(ARM、AVR、RISC-V 都能跑)
  • 输出格式可定制(JUnit、XML、纯文本)

我在一个 STM32 的项目里用过 Unity,当时 Flash 只剩 8KB 了,其他框架根本塞不进去。Unity 加上测试代码,总共才占了 3KB 左右。嗯,这种场景下它就是唯一的选择。

2.1.2 CMock —— 自动生成 Mock 对象

CMock 是 Unity 的搭档,专门用来生成模拟对象。说白了,就是帮你把那些硬件依赖(比如 I2C 读写、GPIO 控制)给替换掉,让单元测试能跑在 PC 上。

我的经验:CMock 生成的代码量比较大,建议只对接口层做 Mock。我曾经试过把整个 HAL 库都 Mock 了,结果编译时间从 10 秒变成了 3 分钟...得不偿失。

2.1.3 Ceedling —— 测试工程管理工具

Ceedling 把 Unity、CMock 和 Ruby 的 Rake 打包在一起,形成了一个完整的测试工程管理方案。你只需要写一个配置文件,它就能自动帮你搞定编译、链接、运行、报告生成。

# project.yml 示例
:project:
  :build_root: build
  :test_file_prefix: test_

:paths:
  :source:
    - src/
  :test:
    - test/
  :support:
    - support/

:unity:
  :vendor: vendor/unity

我个人觉得,Ceedling 最大的价值在于「约定优于配置」。你只要按照它的目录结构放文件,它就能自动识别并构建测试。对于 10 人以下的团队,这套流程非常省心。

2.1.4 PyTest 嵌入式扩展

PyTest 本身是 Python 的测试框架,但通过一些扩展(比如 pytest-embedded、pytest-serial),它可以用来测试嵌入式固件。这种方式适合做集成测试和系统测试,而不是单元测试。

注意:PyTest 方案依赖 Python 运行时,不适合在目标板上跑。它通常是在 PC 端通过串口或调试器与目标板通信,发送命令并解析返回结果。

2.2 选型决策矩阵

光说特点不够,咱们得有个量化的比较。下面这个表格是我根据多年项目经验总结的,你可以直接拿来用。

评估维度 Unity CMock Ceedling PyTest 扩展
资源占用 极低(<5KB) 中等(生成代码多) 中等(依赖 Ruby) 高(依赖 Python)
学习曲线 低(1-2天) 中(需理解 Mock 概念) 中(需熟悉 Ruby) 低(Python 用户友好)
测试类型 单元测试 单元测试(Mock) 单元测试 + 集成测试 集成测试 + 系统测试
自动化程度 手动配置 半自动 全自动 全自动
报告生成 基础 基础 丰富(支持 JUnit) 丰富(Allure 等)
适用场景 资源受限的 MCU 需要隔离硬件依赖 中等规模项目 PC 端测试 + 硬件在环

2.3 选型决策流程

我一般按下面这个思路来选框架,你可以参考一下:

  1. 先问自己:测试跑在哪里?
    • 跑在目标板上 → Unity(资源受限)或 Ceedling(资源充足)
    • 跑在 PC 上 → PyTest 扩展(集成测试)或 Ceedling(单元测试)
  2. 再问:需要 Mock 吗?
    • 需要隔离硬件 → CMock + Unity
    • 不需要 Mock → 纯 Unity 或 PyTest
  3. 最后看:团队技术栈
    • 团队熟悉 C → Unity/CMock/Ceedling
    • 团队熟悉 Python → PyTest 扩展

避坑指南:我曾经在一个项目里强行用 PyTest 做单元测试,结果发现每次测试都要烧录固件到目标板,一个测试用例跑下来要 2 分钟。后来换成 Unity + CMock,在 PC 上跑,100 个用例 10 秒就跑完了。所以啊,选框架一定要搞清楚「测试执行环境」这个前提。

2.4 我的推荐组合

如果你问我个人偏好,我会说:

  • 小项目(< 10 个模块):Unity 就够了,别整那些花里胡哨的
  • 中等项目(10-50 个模块):Ceedling + Unity + CMock,一套搞定
  • 大项目(50+ 模块):Ceedling 做单元测试,PyTest 做集成测试,双管齐下

你想想看,框架只是工具,真正重要的是测试思维。我见过有人用 Unity 写出了非常优雅的测试套件,也见过有人用 Ceedling 把项目搞得一团糟。选对框架只是第一步,后面怎么用才是关键。

小技巧:不管你选哪个框架,建议先搭一个「最小可行测试环境」。写 3-5 个测试用例跑通,确认流程没问题了,再大规模铺开。这样能避免「框架选好了,但跑不起来」的尴尬。

好了,这一章咱们把四个主流框架的特点、适用场景和选型方法都过了一遍。下一章我会手把手带你搭建一个基于 Unity 的测试工程,到时候咱们边写代码边聊。