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

说实话,很多刚入行的工程师觉得MIL测试就是跑跑模型,看看波形对不对。嗯,我当年也这么想过。直到有一次,一个简单的逻辑判断模块,我随便写了几个测试用例就跑过去了。结果呢?集成测试时炸了锅——一个边界条件没覆盖到,导致控制器在特定工况下输出了错误信号。从那以后,我老老实实把测试用例设计方法捡了起来。

今天我们就聊聊三种最实用的方法:等价类划分、边界值分析、因果图法。它们在MIL测试里怎么用?我结合项目经验给你拆开讲。

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

等价类划分,说白了就是把输入数据分成几个“类”。同一类里的数据,程序处理方式是一样的。你只需要从每个类里挑一个代表来测就行。

举个例子。你有个车速信号,范围是0-250 km/h。如果按10 km/h一个步长去测,你得写25个用例。但用等价类划分,你只需要考虑:

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

每个类里选一个值就够了。比如有效类选120,无效类选-5和300。三个用例覆盖了所有情况。

关键点:等价类划分的核心是“找规律”。别被大量输入值吓到,先分类,再测试。

我在项目中遇到过一个问题:一个温度传感器模块,输入范围是-40°C到125°C。测试工程师写了50多个用例,从-40到125每隔5度测一次。我一看就笑了——其实只需要6个用例:有效类里选一个中间值,无效类里选两个边界外的值,再加上边界值本身。这就是等价类划分的威力。

3.2 边界值分析:Bug最爱躲的地方

等价类划分帮你减少了用例数量,但有一个地方它照顾不到——边界。经验告诉我,80%的Bug都藏在边界附近。为什么?因为开发人员写条件判断时,最容易搞错的就是“<”和“<=”这种细节。

边界值分析就是专门对付这个的。它要求你测试每个等价类的边界值,以及边界值附近的值。

还是拿车速信号举例。有效等价类是0-250,那么边界值就是:

  • 最小值:0
  • 略大于最小值:1
  • 最大值:250
  • 略小于最大值:249

再加上无效类的边界:-1和251。一共6个值,覆盖了所有边界情况。

我的习惯:做MIL测试时,我会把边界值分析放在等价类划分之后。先分类,再找边界。这样既全面又高效。

我曾经踩过一个坑。一个油门踏板位置传感器,范围是0-100%。我用了等价类划分,选了50%作为有效类代表。结果呢?模型在100%位置时输出异常——因为开发人员写的是“if (position > 100)”,而不是“if (position >= 100)”。边界值没测,Bug就溜过去了。嗯,从那以后我再也不敢跳过边界值分析了。

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

等价类和边界值主要对付单个输入。但实际项目中,很多功能是多个输入组合决定的。比如一个制动辅助系统,它要根据车速、制动踏板位置、加速度等多个信号来判断是否介入。这时候,因果图法就派上用场了。

因果图法的思路很简单:

  1. 列出所有输入条件(原因)
  2. 列出所有输出结果(结果)
  3. 画出原因和结果之间的逻辑关系(与、或、非)
  4. 根据因果图生成测试用例

举个例子。一个简单的安全气囊点火逻辑:

  • 原因:A = 车速 > 30 km/h,B = 加速度 > 5g
  • 结果:X = 点火
  • 逻辑:X = A AND B

因果图就是:A和B通过“与”门连接到X。测试用例就是:

用例 A B X
1 True True True
2 True False False
3 False True False
4 False False False

你想想看,如果不用因果图,你可能会漏掉“A=True, B=False”这种情况。而这种情况在实际中很可能发生——车速够了但加速度不够,气囊不该点爆。

注意:因果图法在逻辑复杂时特别有用。但别滥用——如果输入条件超过5个,因果图会变得很庞大。这时候我建议先做等价类划分,再对关键组合用因果图。

我在项目中用过一次因果图,效果特别好。那是一个自动紧急制动(AEB)系统,输入条件有车速、相对距离、相对速度、制动踏板位置等七八个。我用因果图梳理了逻辑关系,生成了20多个测试用例。结果MIL测试一次通过,集成测试也没出问题。说白了,因果图帮你把复杂逻辑“可视化”了,不容易遗漏。

3.4 三种方法的组合使用

这三种方法不是孤立的。我个人的习惯是:

  1. 先用等价类划分:把输入数据分类,减少用例数量
  2. 再用边界值分析:针对每个等价类的边界,补充测试用例
  3. 最后用因果图:处理多个输入之间的逻辑组合

举个例子。一个电池管理系统(BMS)的过温保护功能:

  • 输入:电池温度(-20°C到80°C),充电状态(0或1)
  • 输出:过温报警(0或1)
  • 逻辑:如果温度 > 60°C 且 充电状态=1,则报警

用等价类划分:温度分有效类(-20到80)和无效类(<-20或>80)。充电状态分0和1。

用边界值分析:温度边界是-20、-19、60、61、80、81。充电状态边界是0和1。

用因果图:温度>60和充电状态=1是“与”关系。

最终测试用例大概10个左右,覆盖了所有情况。你想想看,如果不用这些方法,你可能要写几十个用例,还不一定能覆盖全。

小技巧:在Simulink里做MIL测试时,可以用Test Sequence模块来组织测试用例。把等价类、边界值、因果图生成的用例都写进去,一键运行。我习惯在测试报告里标注每个用例对应的方法,方便追溯。

3.5 避坑指南

最后,分享几个我踩过的坑:

  • 别只测有效类:无效类往往藏着更多Bug。比如输入范围外的值,模型会不会崩溃?
  • 边界值别只测一个点:我习惯测边界值本身、边界值+1、边界值-1。三个点最保险。
  • 因果图别画得太复杂:如果逻辑太复杂,先拆成子功能,分别画因果图。否则图自己都看不懂。
  • 别忘了时序:MIL测试里,很多Bug是时序相关的。等价类和边界值主要针对稳态,因果图可以加时间维度。

嗯,这三种方法说起来简单,但真正用好需要经验积累。我建议你从一个小功能开始练手,比如一个简单的阈值判断模块。先用等价类划分,再加边界值,最后用因果图处理组合逻辑。练几次就上手了。

下一章我们聊聊测试用例的自动化生成。到时候我会分享一个我自己写的脚本,能自动从Simulink模型里提取边界值和逻辑关系,生成测试用例。敬请期待。