一、课程导论与背景

嵌入式软件测试的挑战

做嵌入式开发这些年,我最大的感触就是——测试这关,真不是随便跑跑就能过的。

你想想看,嵌入式软件跑在什么环境里?单片机、传感器、电机驱动……资源就那么点,RAM 可能只有几 KB,Flash 也抠抠搜搜的。在这种环境下做测试,跟 PC 上那套玩法完全是两码事。

我个人习惯把嵌入式测试的挑战归纳成三点:

  • 资源受限——跑个单元测试框架,内存就爆了。我在一个 STM32 项目上试过用 Unity 做单元测试,结果编译完直接超 ROM 大小,最后只能手写测试桩。
  • 硬件耦合——很多代码跟硬件寄存器、中断、定时器绑得死死的。你没法在 PC 上模拟一个 GPIO 中断的精确时序,对吧?
  • 实时性要求——代码不仅要跑得对,还得跑得够快。我曾经遇到过一个 bug,是因为一个函数里多打印了一条日志,结果导致中断响应超时……这种问题,静态分析根本抓不到。
注意:嵌入式软件测试最大的坑,就是「以为在开发板上跑通了就万事大吉」。实际上,很多 bug 只在特定时序、特定输入组合下才会触发。单元测试和集成验证,就是帮你提前把这些「定时炸弹」挖出来。

单元测试与集成验证的定义

先说说单元测试。说白了,就是把你代码里最小的可测试单元——通常是一个函数——单独拎出来测。给它喂各种输入,看它输出对不对,边界条件处理得好不好。

举个例子:

// 一个简单的温度转换函数
int celsius_to_fahrenheit(int celsius) {
    return (celsius * 9 / 5) + 32;
}

单元测试要测什么?

  • 正常值:0°C → 32°F,100°C → 212°F
  • 边界值:-40°C → -40°F(这个点很有意思,两个温标重合)
  • 异常值:INT_MAX 会不会溢出?

集成验证就不一样了。它测的是多个模块拼在一起能不能正常工作。比如你的温度传感器驱动、数据滤波算法、显示模块,这三个东西合起来,能不能正确地把温度显示在屏幕上?

我记得有一次做车载项目,单元测试全过了,结果集成的时候发现——传感器读回来的数据总是偏大。查了半天,原来是 I2C 通信的时序没对齐,驱动层读到的寄存器值总是多了一位。这就是典型的「单元测试覆盖不到,集成验证才能发现」的问题。

核心区别一句话:

单元测试保证「每个零件是好的」,集成验证保证「零件装在一起还能转」。

课程目标与学习路径

这门课的目标很明确——让你从「会写代码」变成「会测代码」。具体来说:

  1. 掌握单元测试的方法论——怎么写测试用例?怎么设计测试桩?怎么处理硬件依赖?
  2. 学会集成验证的实战技巧——怎么搭测试环境?怎么分析集成问题?怎么自动化?
  3. 建立测试思维——不是测完了就完事,而是能反过来指导你的代码设计。我见过太多人写完代码才想测试,结果发现函数耦合太紧,根本没法测。

学习路径我建议这样走:

阶段 内容 预计时间
基础篇 测试理论、工具选型、环境搭建 2-3 周
单元测试实战 用例设计、桩函数、覆盖率分析 3-4 周
集成验证实战 接口测试、场景测试、自动化框架 3-4 周
进阶与项目 持续集成、测试驱动开发、真实项目演练 2-3 周

我的建议:别急着把所有工具都学一遍。先挑一个你最熟悉的平台(比如 STM32 或者 ARM Cortex-M),把单元测试跑通一个完整的例子。有了手感,再扩展。我曾经带过一个新人,上来就研究五种测试框架,结果一个月过去了,一个测试用例都没写出来。

嗯,课程导论就聊到这儿。下一章我们直接上手——搭一个最简单的单元测试环境,跑你的第一个测试用例。到时候你会发现,其实没那么难。