2. 测试体系架构:HIL/SIL/MIL测试概念、测试金字塔模型、测试策略制定
好,咱们进入第二章。这一章我打算聊聊测试体系的架构。说白了,就是回答一个问题:这么多测试,到底怎么组织才不乱?
我刚入行那会儿,测试就是“焊块板子,上电,看波形”。后来项目越来越复杂,光靠手工点灯根本扛不住。你想想看,一个仪表盘项目,几十个信号、上百条CAN报文、还有各种故障注入……没有体系,那就是一团乱麻。
所以,这一章的核心就是三个东西:MIL/SIL/HIL 的概念、测试金字塔模型、以及怎么制定测试策略。嗯,咱们一个一个来。
2.1 MIL / SIL / HIL:三个层次的测试概念
这三个缩写,你肯定见过。但很多人只是背概念,不知道它们到底怎么用。我用自己的理解给你拆开讲。
2.1.1 MIL(Model-in-the-Loop)—— 模型在环
MIL 是最早的环节。这时候连代码都没有,只有模型。比如你用 Simulink 搭了一个车速计算逻辑,那就在这个模型环境里跑测试。
为什么要做 MIL?
- 验证算法逻辑对不对。比如:车速超过120km/h,报警灯亮不亮?
- 发现设计缺陷。我在项目中遇到过,模型里有个除法,分母可能为零,MIL 阶段就抓出来了。
- 成本最低。改模型比改代码快多了。
2.1.2 SIL(Software-in-the-Loop)—— 软件在环
代码写好了,但还没烧到硬件上。这时候把代码编译成 PC 上能跑的动态库,然后用测试脚本去调用它。
SIL 的价值在哪?
- 验证代码实现和模型是否一致。说白了,就是“代码有没有把模型的意思搞歪”。
- 可以跑大量自动化测试。我做过一个项目,SIL 阶段跑了 2000 多个用例,一晚上跑完。要是等硬件出来再测,得测一个月。
- 调试方便。代码崩了,直接看堆栈,不用接示波器。
2.1.3 HIL(Hardware-in-the-Loop)—— 硬件在环
这是最接近实车的测试。把真实的 ECU(仪表盘硬件)接上,用一台实时仿真机模拟车辆的其他信号(比如发动机转速、车速、灯光状态)。
HIL 测什么?
- 硬件接口:IO 口电平对不对?PWM 波形准不准?
- 通信协议:CAN/LIN 报文收发是否正常?
- 故障注入:比如某个传感器短路了,仪表盘会不会正确报警?
- 时序和实时性:从收到 CAN 报文到屏幕刷新,延迟多少毫秒?
我记得有一次做 HIL 测试,发现仪表盘在收到连续高速 CAN 报文时,偶尔会丢一帧。这个问题在 SIL 阶段完全没暴露,因为 PC 的处理速度比真实 MCU 快太多了。这就是 HIL 不可替代的原因。
| 测试层级 | 测试对象 | 主要目的 | 执行速度 | 成本 |
|---|---|---|---|---|
| MIL | 模型 | 验证算法逻辑 | 最快 | 最低 |
| SIL | 代码(PC环境) | 验证代码实现 | 快 | 低 |
| HIL | 真实硬件 | 验证硬件接口和实时性 | 慢(实时运行) | 高 |
2.2 测试金字塔模型
这个概念最早来自软件测试领域,但用在仪表盘测试上,同样适用。说白了就是:底层测试要多,上层测试要少。
为什么?因为底层测试(比如单元测试、MIL/SIL)跑得快、成本低、发现问题早。上层测试(比如 HIL、系统测试)跑得慢、成本高、发现问题晚。
一个典型的仪表盘测试金字塔,从下往上大概是这样的:
- 底层:单元测试 / MIL 测试 —— 数量最多,覆盖每个函数、每个模型模块。
- 中间层:集成测试 / SIL 测试 —— 验证模块之间的交互,比如 CAN 接收模块和显示模块的配合。
- 顶层:系统测试 / HIL 测试 —— 验证整个仪表盘作为一个系统,是否满足需求。
我的经验:很多团队把 HIL 测试当成“主力”,花大价钱买设备,结果底层测试几乎不做。这是典型的倒金字塔。我曾经接手过一个项目,HIL 测试天天报 bug,一查,全是底层逻辑问题。如果 MIL 阶段多花两天,HIL 阶段能省两周。
所以,我建议的比例是:MIL/SIL 测试占 60%,集成测试占 25%,HIL 测试占 15%。当然,这个比例不是死的,但方向一定要对。
2.3 测试策略制定
有了概念,有了模型,接下来就是怎么落地。测试策略,说白了就是回答三个问题:
- 测什么? —— 测试范围
- 怎么测? —— 测试方法
- 测多少? —— 测试深度
2.3.1 基于风险的测试策略
我个人最推崇的方法。不是所有功能都值得花同样的精力去测。比如:
- 高优先级:安全相关功能(车速显示、报警灯、故障提示)。这些必须全覆盖,包括正常、边界、异常。
- 中优先级:常用功能(里程显示、油耗计算)。覆盖主要场景,边界值可以抽测。
- 低优先级:辅助功能(主题切换、语言设置)。覆盖正常场景即可。
我曾经犯过一个错误:在一个项目里,把所有功能都按“高优先级”去测,结果测试周期拖了两个月,最后客户催得紧,反而漏掉了几个关键的安全用例。嗯,从那以后,我学会了“抓大放小”。
2.3.2 测试用例设计原则
不管哪个层级,测试用例的设计都有一些通用原则:
- 等价类划分:把输入分成几个“等价”的区间,每个区间选一个代表。比如车速 0-60 是一个区间,60-120 是另一个区间。
- 边界值分析:bug 往往出现在边界上。比如报警阈值是 120km/h,那 119、120、121 这三个值必须测。
- 错误推测:凭经验猜哪里容易出问题。比如 CAN 总线突然断开、电源电压波动。
2.3.3 自动化测试策略
仪表盘测试,不做自动化,迟早累死。但自动化也不是万能的。我的建议是:
- MIL/SIL:必须全自动化。脚本跑一遍,结果自动比对。我习惯用 Python + Simulink Test 或者 VectorCAST。
- HIL:尽量自动化。但有些场景(比如视觉检查屏幕显示内容)还是需要人工介入。不过现在也有图像识别工具可以辅助。
- 回归测试:每次代码变更后,自动跑一遍核心用例。这个投入产出比最高。
我记得有一次,一个项目改了 CAN 报文解析的底层代码,结果把仪表盘的里程显示搞坏了。幸好我们有自动化回归测试,第二天一早就发现了。要是靠人工测,可能到交付前才发现,那就惨了。
2.4 小结
这一章的内容,说白了就是三句话:
- MIL/SIL/HIL 是三个不同层次的测试,各有各的用处,谁也替代不了谁。
- 测试金字塔告诉我们,底层测试要多做,上层测试要精做。
- 测试策略的核心是“基于风险”,把有限的资源花在刀刃上。
下一章,我会讲具体的测试环境搭建。到时候咱们聊聊怎么搭一个靠谱的 HIL 台架,以及那些年我踩过的坑。嗯,先到这儿吧。