3. 测试用例设计基础:等价类划分、边界值分析、因果图法在MIL中的应用

做MIL测试这么多年,我见过太多人一上来就对着模型猛点,跑几个仿真就算完事。结果呢?覆盖率惨不忍睹,bug漏得跟筛子一样。说白了,测试用例设计才是MIL测试的硬功夫。今天咱们就聊聊三种最基础、也最实用的方法——等价类划分、边界值分析和因果图法。

3.1 等价类划分:别做无用功

等价类划分的核心思想很简单:把输入域分成若干「等价类」,每个类里选一个代表就够了。为什么?因为同一个等价类里的值,程序处理逻辑是一样的。

举个例子,你有个车速信号,范围是0~250 km/h。你难道要测0、1、2、3……250每个值?那得测到猴年马月去。我一般这么分:

  • 有效等价类:0 ≤ 车速 ≤ 250
  • 无效等价类:车速 < 0 和 车速 > 250

每个类里挑一个值,比如0、125、250、-1、251,五个用例就覆盖了全部范围。效率翻倍,效果不打折。

我的习惯: 做MIL测试时,我会先列一个「输入信号清单」,把每个信号的取值范围、数据类型、物理意义都写清楚。然后对着清单做等价类划分,这样不容易漏。

但要注意,等价类划分不是万能的。有些信号是离散的,比如档位信号只有P、R、N、D四个值,那每个值就是一个等价类,没法再「划分」了。这种情况,老老实实全测。

3.2 边界值分析:bug最喜欢的地方

做测试的都知道,bug最喜欢藏在边界上。为什么?因为开发写代码时,最容易在边界条件上犯迷糊——比如用了 < 还是 ≤,边界值+1还是-1。

边界值分析就是专门抓这种bug的。它和等价类划分是黄金搭档:等价类划分帮你「选点」,边界值分析帮你「选边界上的点」。

还是拿车速信号举例,范围0~250。边界值分析要测哪些点?

边界类型 测试值 说明
下边界 0 最小值
下边界+1 1 紧邻最小值的有效值
上边界-1 249 紧邻最大值的有效值
上边界 250 最大值
下边界-1 -1 无效值,略低于最小值
上边界+1 251 无效值,略高于最大值
我曾经踩过的坑: 有一次做ACC(自适应巡航)的MIL测试,目标距离信号的边界是200米。我测了0、1、199、200、-1、201,觉得万无一失。结果模型在199.5米时出了bug——因为模型内部用了浮点数比较,而我只测了整数边界。从那以后,浮点数边界我至少会测三个点:边界值、边界值±ε(一个很小的浮点数增量)。

3.3 因果图法:理清复杂逻辑

等价类划分和边界值分析处理的是单个输入。但实际项目中,很多功能是多个输入组合决定的。比如一个安全气囊点爆逻辑,要同时考虑车速、碰撞加速度、乘员位置等多个信号。这时候,因果图法就派上用场了。

因果图法的思路是:先画「因」(输入条件)和「果」(输出结果),再分析它们之间的逻辑关系(与、或、非、异或等),最后根据因果图生成测试用例。

我画个简单的因果图给你看:

因果图示例:安全气囊点爆逻辑 因果图示例:安全气囊点爆逻辑 原因1:车速 > 30 km/h 原因2:碰撞加速度 > 阈值 原因3:乘员位置正常 中间:碰撞确认 结果:点爆气囊 AND AND 说明: 原因1 AND 原因2 → 中间节点(碰撞确认) 中间节点 AND 原因3 → 结果(点爆气囊)

根据这个因果图,我们可以生成测试用例:

用例编号 原因1 原因2 原因3 预期结果
TC-01 真 真 真 点爆
TC-02 真 真 假 不点爆
TC-03 真 假 真 不点爆
TC-04 假 真 真 不点爆
TC-05 假 假 真 不点爆

你想想看,如果不画因果图,你可能会凭直觉组合几个用例,大概率会漏掉「原因1真、原因2真、原因3假」这种组合——而恰恰是这种组合最容易出bug。

核心要点: 因果图法特别适合处理「多输入条件决定单一输出」的逻辑。在MIL测试中,很多控制策略(如故障诊断、模式切换、安全保护)都符合这个特征。

3.4 三种方法在MIL中的实际应用

说了这么多理论,咱们看看在Simulink的MIL测试里,这三种方法到底怎么用。

第一步:分析模型接口

打开你的Simulink模型,找到被测模块的输入输出端口。我一般会列个表:

端口名 数据类型 取值范围 物理意义
VehSpd single 0 ~ 250 车速 (km/h)
BrkPedal boolean 0 / 1 制动踏板状态
EngSpd uint16 0 ~ 8000 发动机转速 (rpm)

第二步:选择方法

  • 连续信号(如车速、转速、温度):用等价类划分 + 边界值分析
  • 离散信号(如档位、模式、状态):用等价类划分(每个值一个类)
  • 组合逻辑(如多个条件决定一个输出):用因果图法

第三步:生成测试用例

把三种方法的结果合并,去重,就得到最终的测试用例集。我习惯用Excel管理,每行一个用例,列包括:用例ID、输入值、预期输出、覆盖的方法、测试结果。

我的经验: 别指望一次把所有用例都设计完美。先跑一轮,看看覆盖率报告,再补充遗漏的边界和组合。迭代两三次,覆盖率就能到90%以上。

3.5 避坑指南

做测试用例设计这些年,我踩过不少坑。挑几个典型的说说:

  • 别忽略「无效等价类」。很多人只测有效值,觉得无效值不会出现。但模型要有鲁棒性,万一传感器故障送了个异常值呢?我见过一个项目,就是因为没测负值,结果模型在负值输入时直接崩了。
  • 边界值分析要结合数据类型。整型边界和浮点型边界不一样。整型边界就是±1,浮点型边界要考虑精度和舍入误差。
  • 因果图别画得太复杂。超过5个原因,因果图就变得难以管理。这时候可以考虑拆分成多个子功能,分别画因果图。
  • 别忘了时序。MIL测试里,很多bug是时序相关的。比如两个信号到达的先后顺序不同,结果就不同。因果图法本身不处理时序,需要你额外补充时序相关的用例。
我曾经犯过的错: 有一次做电池管理系统的MIL测试,我用等价类划分把SOC(荷电状态)分成了0~20%、20%~80%、80%~100%三个区间,每个区间选了一个值。结果漏掉了SOC在20%附近来回跳变的情况——模型在边界附近频繁切换充电/放电模式,导致继电器寿命急剧下降。从那以后,我对于有滞回特性的逻辑,一定会额外设计「边界来回穿越」的测试用例。

好了,关于测试用例设计的基础方法,今天就聊到这儿。这三种方法看着简单,但真正用好、用透,需要大量实践。下次你拿到一个新模型,不妨先花半小时做等价类划分和边界值分析,再画个因果图理理逻辑——你会发现,测试效率至少提升一倍。