第四章:测试用例设计基础

等价类划分法:把无穷变成有限

做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个呢?组合数会爆炸。因果图法就是用来解决这个问题的。

因果图法的核心思路:

  1. 列出所有输入条件(因):比如车速、刹车状态、ACC状态等
  2. 列出所有输出结果(果):比如激活EBA、点亮警告灯等
  3. 画出因果关系图:用逻辑门(与、或、非)连接因和果
  4. 生成决策表:把因果图转成表格,每一列就是一个测试用例

举个例子,一个自动紧急制动(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个,我建议拆分成多个子功能来测。否则决策表会变得很大,反而不好维护。

三种方法的组合使用

实际项目中,这三种方法不是孤立的。我一般这样用:

  1. 先用因果图法:理清功能逻辑,找出关键组合
  2. 再用等价类划分:对每个输入条件,划分有效和无效等价类
  3. 最后用边界值分析:对每个等价类的边界,补充边界值测试

举个例子,测试一个ACC自适应巡航的设定速度功能:

  • 因果图:设定速度有效(30-150 km/h)AND 车辆静止 → 激活ACC
  • 等价类:有效速度(30-150)、无效低速(<30)、无效高速(>150)
  • 边界值:29、30、31、149、150、151

这样一套组合拳下来,测试用例既不会太多,又能保证覆盖率。我做过统计,用这种方法设计的用例,现场回归测试的Bug漏测率不到3%。

总结一下:

等价类划分解决「测多少」的问题,边界值分析解决「测哪里」的问题,因果图法解决「怎么组合」的问题。三者结合,就是HIL测试用例设计的黄金组合。

嗯,这一章的内容就到这里。下一章我们聊聊「如何从需求文档中提取测试点」——这可是个技术活,我踩过的坑可不少。