返回首页

嵌入式单元测试:原则

本文分析了嵌入式开发中单元测试的优势:控制、重构、文档。描述了缺点及其解决方案,以及编写测试的 20 条原则,包括 AAA 和目标上 HIL。适合中高级固件开发者。

如何在嵌入式固件中实现单元测试
Advertisement 728x90

嵌入式开发中的单元测试:原则与最佳实践

嵌入式系统固件单元测试能验证代码功能,支持安全重构,并记录API。代码作者编写初始测试套件,同事补充独立校验。这对涉及DTC要求的协议如UDS尤为实用。

实施单元测试的好处

单元测试通过固定输入调用函数并验证输出,类似于SIL测试。它解决多项关键挑战:

  • 功能验证:测试确认代码行为正确。
  • 安全重构:修改不会破坏现有功能。
  • 文档化:测试中用法示例清晰,无需额外注释。
  • 完成标准:测试通过后才转向下一组件。
  • 贡献追踪:领导可要求测试验证开发者工作。

测试将责任从作者转移:如果昨天代码通过,问题出在别处。它们通过覆盖率指标发现不可达代码,推动模块化结构,避免巨型函数和魔法数字的“意大利面条代码”。

Google AdInline article slot

这就像PCB设计:在原理图阶段添加测试点,而不是焊好后再补。软件亦然——从一开始就写小函数。测试确保跨平台(ARM Cortex-M、RISC-V、PowerPC)和编译器(GCC、IAR、Clang)的可移植性。回归测试捕捉新变更破坏旧代码的情况。

运行测试免费且快速,不像手动测试易受人为偏差影响。对管理者,这是进度指标。调试更简单:测试报告直指故障函数。

缺点与应对策略

单元测试有局限,但标准实践可解决。

Google AdInline article slot
  • 内存限制:Flash有限的MCU上,将测试分组,通过引导加载器和CLI顺序运行。在CI/CD(如Jenkins)中自动化。或用Flash更大的MCU测试,再移植验证代码。
  • 测试自身Bug:用代码审查,编写健壮、抗故障的测试。
  • 过度测试:聚焦代码覆盖率(工具如Testwell CTC++)或规范要求。每要求一个测试。
  • 无集成覆盖:搭配集成测试。经典地铁门单元测试梗说明,单元测试无法保证整体系统。

编写单元测试的原则

模块作者编写首套测试——他们最懂领域。将代码和测试分离到不同目录。

  • 每个测试检查一件事。
  • 修复Bug前,先为其写测试。
  • 确定性:不用rand(),固定输入。
  • 简洁:短小、可读、一屏可见。
  • AAA:Arrange(准备)、Act(执行)、Assert(断言)。
  • 无if语句——用ASSERT宏。
  • 覆盖边界情况。
  • 集成CI,通过CLI(UART)运行。
  • 重构友好。
  • 测试顺序不影响结果。
  • 通过Shell/Putty在目标硬件(HIL)上运行。

测试要么通过,要么删除。修复测试优先于生产代码。同事编写的测试提升无偏覆盖。

测试框架可能复杂化,超过产品本身——如测试音频编解码器(SGTL5000、MAX9860)。但这种纪律带来可靠性回报。

Google AdInline article slot

关键要点

  • 从第一天起启动单元测试,确保模块化和可移植性。
  • 自己写测试:深入理解加速进程。
  • 坚持AAA和确定性,获得稳固结果。
  • 通过CLI在目标硬件运行——HIL验证必备。
  • 补充集成测试,获取全貌。

— Editorial Team

Advertisement 728x90

继续阅读