测试_05:自动化测试与 CI——把测试塞进流水线 📅 2026/8/25 13:37:54 适用人群单元测试写了几个但每次都是手动在 PC 上跑一下看看改了十处代码才想起来好像该跑一下测试结果早崩了都不知道的同学。这是16_嵌入式测试软件篇的收口文。上篇测试_04解决了测依赖硬件的代码这篇解决怎么让测试自动、持续地跑把前面 02/03/04 串成一条流水线。读完你能得到① 为什么手工测不靠谱CI 是什么② 用 GitHub Actions / 本地脚本提交即跑测试③ 静态检查测试_03怎么挂进同一条流水线④ 代码覆盖率 gcov/lcov 白话版以及它的陷阱⑤ 嵌入式怎么做PC 测逻辑 板子只跑冒烟。一、手工测的痛假设你现在的状态本地有一套 Unity 测试平时这么用——gcc utils.c test_utils.c unity.c-otest_utils./test_utils看起来没问题。但真实情况是忘了跑改完代码直接提交测试压根没跑bug 跟着进了仓库。只在自己机器跑过你的环境能过同事的机器编译器版本不同一拉就红。没标准什么叫测过了你心里有数但流水线不知道。CI持续集成Continuous Integration就是来解决这个的你一提交代码服务器自动拉下来、编译、跑测试、跑静态检查红了当场告诉你。一句话手工测靠自觉CI 靠流程。自觉会忘流程不会。二、CI 长什么样以 GitHub Actions 为例最精简的 CI 配置.github/workflows/test.ymlname:embedded-testson:[push,pull_request]jobs:test:runs-on:ubuntu-lateststeps:-uses:actions/checkoutv4-name:编译并跑单元测试run:|gcc utils.c test_utils.c unity.c -o test_utils ./test_utils-name:静态分析run:|cppcheck --error-exitcode1 --enableall --stdc99 src/这段代码的意思是每次 push 或开 PRGitHub 的服务器就自动做这两件事。任何一步非零退出整个 CI 标红提交被拦下。没有 GitHub 也没关系。本地用个Makefile 一句make test也行关键是一键跑全部检查而不是手动敲三条命令。下面给个最小 MakefileCC gcc SRC utils.c test_utils.c unity.c test: $(CC) $(SRC) -o test_utils ./test_utils static: cppcheck --error-exitcode1 --enableall --stdc99 src/ check: test staticmake check一条命令单元测试 静态分析全跑。把测试变成肌肉记忆。三、把静态检查挂进来呼应测试_03测试_03讲的-Wall -Werror cppcheck正好作为 CI 的第一、二关# 第一关警告清零任何 warning 都编不过gcc-Wall-Wextra-Werror-csrc/*.c# 第二关静态分析发现潜在 bug / 违反规范cppcheck --error-exitcode1--enableall--stdc99 src/# 第三关单元测试验证行为正确./test_utils三关全过代码才算健康。这就是把代码质量从靠人盯变成靠机器卡。面试时这句特别好使我们工程的 CI 三关——编译零警告、cppcheck 静态分析、Unity 单元测试任何一关红都合不进去。这比我写完了会 review专业太多。四、代码覆盖率你的测试到底覆盖了多少覆盖率工具回答一个问题“你写的测试跑到了多少行代码”GCC 用 gcov、配合 lcov 出报告# 编译时插桩gcc--coverageutils.c test_utils.c unity.c-otest_utils# 跑测试./test_utils# 生成报告gcov utils.c# 命令行看每行是否被覆盖lcov--capture--directory.--output-file cov.info genhtml cov.info --output-directory cov_html# 生成网页报告报告会告诉你哪些函数 100% 覆盖哪行if分支从来没被测到。 覆盖率是个下限指标低覆盖率一定说明测少了但高覆盖率不代表测对了。见过有人为了冲 100% 写TEST_ASSERT_TRUE(1)这种无效断言——跑通了但什么都没验证。别这么干。覆盖率的陷阱陷阱说明追求 100%边际成本高、收益低核心逻辑覆盖到就行无效断言冲覆盖率TEST_ASSERT_TRUE(1)跑通但没验证行为只看行覆盖不看分支一行代码但if/else只测了一半分支没覆盖五、嵌入式怎么做PC 测逻辑板子只跑冒烟回看测试_01说的把硬件无关逻辑抽到 PC 上测。落到 CI 上就是两类测试分开CI 自动跑每次提交 ├─ PC 单元测试算法/协议/状态机Unity秒级 └─ 静态分析cppcheck 编译零警告 板端手动/定期跑烧录后 └─ 冒烟测试上电能起、关键功能能用见 测试_06~10MCU 上跑不了庞大的测试框架也跑不了 gcov所以逻辑全在 PC 的 CI 里验板子只做能不能起来的冒烟。这是嵌入式测试最务实的分工。这套分工直接对应前面几篇测试_02/04的逻辑测试在 PC测试_06~10的板级/系统测试在硬件上。六、新手必踩的坑#坑后果正确做法1CI 挂了没人看等于没挂红了就挡合入强制修2只在自己机器测过别人一拉就红用 CI 在干净环境跑3覆盖率凑数假安全断言要真验证行为4把所有测试塞板子慢、难维护PC 测逻辑、板子只冒烟5测试不独立顺序一变就挂每个测试 setUp/tearDown 复位七、总结软件测试 5 篇收口篇主题一句话01总览测试是预防调试是救火02单元测试Unity 在 PC 上测纯函数03静态分析不运行也能找 bugMISRA 兜底04桩/模拟用接口抽象 桩顶掉硬件依赖05自动化/CI提交即跑覆盖率看覆盖一句话总结手工测靠自觉会忘CI 把编译零警告 静态分析 单元测试串成流水线红了就挡合入嵌入式是PC 测逻辑、板子只冒烟覆盖率看下限不迷信 100%。CI 平台不限于 GitHub ActionsGitLab CI、本地 Makefile 思路一致gcov/lcov 是 GCC 配套工具搜 “gcov lcov 教程” 即可上手。覆盖率数据以你项目的实际配置为准。本站相关测试_01~04软件测试前四篇、测试_03静态分析、测试_06硬件测试起手。下一篇测试_06_上电与电源测试——电压电流纹波功耗怎么量