3. 测试验证体系:V模型、单元测试、集成测试、系统测试、验收测试
好,咱们今天聊聊测试验证体系。说实话,很多工程师一听到「测试」两个字,脑子里蹦出来的就是「找bug」。其实远不止这么简单。我个人习惯把测试看作一个完整的质量保障链条,从你写第一行代码开始,它就已经在运转了。
为什么要有体系?你想想看,一个医疗贴片,里面跑着控制算法,外面连着人体。如果等到整机做完了才发现问题,那代价可就大了去了。我在项目中遇到过不止一次,因为单元测试没做透,结果集成的时候出了大乱子,最后不得不返工改方案。嗯,那滋味可不好受。
3.1 V模型:测试不是最后才做的事
V模型,说白了就是把开发和测试对应起来。左边是开发阶段,右边是测试阶段,中间一条线连起来。你写需求文档的时候,验收测试的用例就该开始构思了。你做详细设计的时候,系统测试的方案也该有个雏形了。
我刚开始做项目时,总觉得测试是测试工程师的事。后来吃了几次亏才明白——测试验证必须从项目第一天就介入。V模型的核心思想就是这个:早发现,早修复,成本最低。
V模型的关键对应关系:
- 需求分析 ↔ 验收测试
- 系统设计 ↔ 系统测试
- 详细设计 ↔ 集成测试
- 编码实现 ↔ 单元测试
举个例子。你在设计贴片的电源管理模块时,如果只想着「能工作就行」,没考虑电池低电量时的行为。等到系统测试时才发现,低电量下ADC采样会漂移,导致心率数据不准。这时候再改,硬件已经定型了,只能打补丁。你说难受不难受?
3.2 单元测试:把每个零件都拧紧
单元测试,测的是最小的可测试单元。在嵌入式里,通常就是一个函数、一个模块、一个驱动接口。我个人习惯把单元测试叫做「白盒测试」,因为你得知道里面是怎么写的,才能设计出有效的用例。
为什么要做单元测试?我打个比方。你组装一个精密仪器,每个螺丝都要拧到规定的扭矩。如果有个螺丝没拧紧,整台机器可能就废了。单元测试就是检查每个「螺丝」的扭矩。
我的经验:单元测试覆盖率至少要达到80%以上,关键模块(比如安全相关的看门狗、ADC采样滤波)要做到100%。我曾经在一个项目中,因为漏测了一个边界条件——温度传感器在-10°C时的返回值处理,结果在低温测试时直接死机。从那以后,边界值测试我从来不敢省。
单元测试怎么做?我给你看个简单的例子。假设我们有个函数,用来计算电池剩余电量的百分比:
// battery.c
uint8_t calc_battery_percent(uint16_t voltage_mv) {
if (voltage_mv >= 4200) return 100;
if (voltage_mv <= 3200) return 0;
// 线性映射:3200mV -> 0%, 4200mV -> 100%
return (uint8_t)((voltage_mv - 3200) * 100 / 1000);
}
单元测试用例至少应该覆盖:
- 正常值:3500mV → 应该返回30%
- 边界值:3200mV → 返回0%,4200mV → 返回100%
- 异常值:3100mV(低于最低值)→ 返回0%
- 溢出值:4300mV(高于最高值)→ 返回100%
注意:单元测试不是跑一遍就完事了。每次代码变更,都要重新跑一遍所有单元测试。我建议用自动化测试框架,比如Ceedling或者Unity,每次提交代码自动触发。别问我为什么强调这个——我曾经手贱改了一行代码,结果把三个模块的测试都搞挂了,要不是自动化跑出来,我可能到集成阶段才发现。
3.3 集成测试:把零件组装起来看效果
单元测试通过,不代表模块之间就能好好配合。集成测试就是干这个的——把各个模块拼在一起,看它们能不能协同工作。
在医疗贴片项目里,集成测试特别重要。为什么?因为贴片里涉及多个子系统:传感器采集、数据处理、无线通信、电源管理。每个子系统单独跑都没问题,但一集成,问题就来了。
我记得有个项目,传感器驱动和无线模块单独测试都OK。但集成后发现,传感器中断和无线发送中断冲突了,导致数据包丢失。这种问题,单元测试是测不出来的,必须靠集成测试来抓。
集成测试的策略,我一般分两种:
- 大爆炸集成:所有模块一次性拼起来测。快,但出了问题很难定位。
- 增量集成:从核心模块开始,一个一个往上加。慢,但定位问题快。
我个人更推荐增量集成。尤其是医疗设备,安全第一,宁可慢一点,也要稳一点。
3.4 系统测试:站在用户角度看问题
系统测试,测的是整个产品。这时候不看代码了,看的是产品能不能满足需求。说白了,就是模拟真实使用场景,看贴片能不能正常工作。
系统测试的用例设计,要覆盖:
- 功能测试:所有功能是否按需求实现?比如心率监测、数据上传、低电量报警。
- 性能测试:响应时间、功耗、数据精度是否达标?
- 可靠性测试:长时间运行会不会死机?数据会不会丢失?
- 环境测试:高温、低温、湿度、振动下能不能正常工作?
- 安全测试:异常操作会不会导致危险?比如贴片脱落、电池短路。
避坑指南:我曾经在系统测试阶段发现,贴片在用户出汗时,电极接触电阻变化导致心率数据跳变。这个问题在实验室环境下根本测不出来,因为实验室的皮肤是干燥的。所以系统测试一定要尽可能模拟真实场景,包括「不理想」的场景。
3.5 验收测试:客户说行才算行
验收测试,是最后一道关。通常由客户或者第三方机构来做。他们不看你的代码写得有多漂亮,只看产品能不能满足合同要求。
在医疗领域,验收测试往往还涉及法规符合性。比如FDA的510(k)或者CE的MDR认证。这些测试有严格的流程和标准,不是你想怎么测就怎么测的。
验收测试的文档特别重要。我建议在项目一开始,就把验收标准和测试方法写清楚。不然到了验收阶段,客户说「我觉得这个指标不行」,你说「我们设计时就是这么定的」,那就扯皮了。
验收测试通过后,产品才能正式发布。但别忘了,测试验证不是一次性的。产品上市后,如果发现新的问题,或者有软件更新,整个测试流程要重新走一遍。嗯,这就是医疗设备的严谨之处。
我的建议:把测试验证看作一个持续的过程,而不是一个阶段。从需求到发布,每个环节都要有对应的测试活动。这样虽然前期投入大,但后期返工的成本会小得多。我在多个项目中验证过这个道理——前期省下的测试时间,后期往往要花十倍的时间来还债。
好了,关于测试验证体系,今天就聊这么多。下一章我们讲讲具体的测试工具和环境搭建,到时候我会分享一些我常用的「私房工具」。