第二章 测试框架选型:主流框架对比与选型决策矩阵
做嵌入式固件测试,选框架是个绕不开的坎。我见过不少团队,代码写得挺漂亮,一到测试就抓瞎——要么框架太重跑不动,要么太轻啥也测不了。今天咱们就把市面上几个主流框架掰开揉碎,看看它们到底适合什么场景。
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 选型决策流程
我一般按下面这个思路来选框架,你可以参考一下:
- 先问自己:测试跑在哪里?
- 跑在目标板上 → Unity(资源受限)或 Ceedling(资源充足)
- 跑在 PC 上 → PyTest 扩展(集成测试)或 Ceedling(单元测试)
- 再问:需要 Mock 吗?
- 需要隔离硬件 → CMock + Unity
- 不需要 Mock → 纯 Unity 或 PyTest
- 最后看:团队技术栈
- 团队熟悉 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 的测试工程,到时候咱们边写代码边聊。