第四章:测试用例设计基础
等价类划分法:把无穷变成有限
做HIL测试,最头疼的是什么?
是测试用例太多了,测不完。
你想想看,一个车速信号,从0到300 km/h,每个值都测一遍?那得测到猴年马月去。我刚开始做HIL测试那会儿,就犯过这个傻。领导让我测一个油门踏板的线性度,我愣是写了200多个测试用例,从0%踩到100%,每0.5%一个点。结果呢?测了三天三夜,最后发现真正出问题的,反而是那几个边界值。
等价类划分法,说白了就是「分类」。把输入域分成几个「等价类」,每个类里挑一个代表值来测。如果这个代表值通过了,那整个类的其他值大概率也没问题。
核心原则:
- 有效等价类:符合需求的输入值
- 无效等价类:不符合需求的输入值
举个例子,一个BMS的电压采集功能,要求输入范围是2.5V到4.2V。那等价类怎么分?
| 输入条件 | 有效等价类 | 无效等价类 |
|---|---|---|
| 电压值 | 2.5V ≤ V ≤ 4.2V | V < 2.5V, V > 4.2V |
嗯,这里要注意。无效等价类往往不止一个。低于下限是一个,高于上限是另一个。我见过不少新手,把无效等价类只写成一个「超出范围」,结果漏测了高压侧的保护逻辑。
我个人习惯,每个无效等价类都单独写一个用例。为什么?因为一个用例里如果同时有多个无效输入,你根本不知道是哪个触发了故障。这在HIL测试里特别重要——你是在验证ECU的故障诊断逻辑,不是在做压力测试。
边界值分析法:Bug最喜欢待的地方
等价类划分解决了「测太多」的问题,但它有个盲区——边界。
为什么会这样?因为程序员写代码的时候,最容易写错的就是边界条件。比如「if (voltage >= 2.5)」写成「if (voltage > 2.5)」,差了一个等号,结果2.5V这个点就被漏掉了。
边界值分析法,就是专门来抓这种Bug的。
我的经验法则:
每个边界,测三个点:边界值本身、边界值-1、边界值+1。
如果边界是闭区间,那边界值本身和边界值+1(或-1)都要测。
还是那个BMS电压的例子。范围是2.5V到4.2V,边界值怎么取?
| 边界位置 | 测试值 | 说明 |
|---|---|---|
| 下边界 | 2.49V, 2.50V, 2.51V | 低于、等于、高于下限 |
| 上边界 | 4.19V, 4.20V, 4.21V | 低于、等于、高于上限 |
我记得有一次,测试一个ESP系统的轮速传感器。轮速范围是0到250 km/h。我用等价类划分,选了50、100、150三个点,全过了。但我不放心,又加了边界值测试——0 km/h、1 km/h、249 km/h、250 km/h、251 km/h。结果你猜怎么着?在1 km/h这个点上,ESP误报了故障。原因是代码里写的是「if (wheel_speed < 1)」,应该写成「if (wheel_speed <= 1)」。就这一个等号,差点让ESP在低速时频繁报警。
避坑指南:
我曾经吃过一次亏,只测了边界值本身,没测边界值±1。结果边界值本身通过了,但边界值+1的那个点触发了故障。后来我养成了一个习惯:边界值测试,至少测三个点——边界、边界-步长、边界+步长。步长取决于系统精度,一般是1或0.1。
因果图法:理清复杂逻辑
等价类和边界值,对付单个输入条件很有效。但HIL测试里,很多功能是多个条件组合触发的。比如:「当车速大于30 km/h且刹车踏板被踩下时,激活紧急制动辅助」。这里有两个条件,组合起来有4种情况。
如果条件增加到5个、6个呢?组合数会爆炸。因果图法就是用来解决这个问题的。
因果图法的核心思路:
- 列出所有输入条件(因):比如车速、刹车状态、ACC状态等
- 列出所有输出结果(果):比如激活EBA、点亮警告灯等
- 画出因果关系图:用逻辑门(与、或、非)连接因和果
- 生成决策表:把因果图转成表格,每一列就是一个测试用例
举个例子,一个自动紧急制动(AEB)系统,触发条件如下:
- 条件1:车速 > 30 km/h
- 条件2:与前车距离 < 安全距离
- 条件3:驾驶员未踩刹车
输出:激活AEB
因果图是这样的:条件1 AND 条件2 AND 条件3 → 输出AEB。
决策表就是:
| 用例编号 | 车速 > 30 | 距离 < 安全 | 未踩刹车 | 激活AEB |
|---|---|---|---|---|
| 1 | Y | Y | Y | Y |
| 2 | Y | Y | N | N |
| 3 | Y | N | Y | N |
| 4 | N | Y | Y | N |
你看,3个条件,一共8种组合。但通过因果图,我们只选了4个关键组合。为什么?因为有些组合是冗余的。比如条件1为N时,不管条件2和3是什么,输出都是N。这就是因果图法的威力——帮你剪枝。
我个人习惯,因果图法特别适合用在功能安全相关的测试上。比如ASIL C或ASIL D的功能,逻辑复杂,组合多,用因果图法可以保证覆盖所有关键路径,又不会让用例数量失控。
一个小技巧:
画因果图的时候,别急着画。先把所有「因」列出来,再列所有「果」。然后用「与门」「或门」「非门」去连。如果发现某个「果」依赖的「因」超过4个,我建议拆分成多个子功能来测。否则决策表会变得很大,反而不好维护。
三种方法的组合使用
实际项目中,这三种方法不是孤立的。我一般这样用:
- 先用因果图法:理清功能逻辑,找出关键组合
- 再用等价类划分:对每个输入条件,划分有效和无效等价类
- 最后用边界值分析:对每个等价类的边界,补充边界值测试
举个例子,测试一个ACC自适应巡航的设定速度功能:
- 因果图:设定速度有效(30-150 km/h)AND 车辆静止 → 激活ACC
- 等价类:有效速度(30-150)、无效低速(<30)、无效高速(>150)
- 边界值:29、30、31、149、150、151
这样一套组合拳下来,测试用例既不会太多,又能保证覆盖率。我做过统计,用这种方法设计的用例,现场回归测试的Bug漏测率不到3%。
总结一下:
等价类划分解决「测多少」的问题,边界值分析解决「测哪里」的问题,因果图法解决「怎么组合」的问题。三者结合,就是HIL测试用例设计的黄金组合。
嗯,这一章的内容就到这里。下一章我们聊聊「如何从需求文档中提取测试点」——这可是个技术活,我踩过的坑可不少。