4、测试用例设计:基于模型的测试方法、等价类与边界值分析、HIL场景的时序约束

好,咱们进入第四章。这一章我打算聊聊测试用例设计。说实话,很多团队在HIL(硬件在环)上栽跟头,不是设备不行,而是测试用例设计得不够扎实。你想想看,一个HIL台架跑起来,电费、设备折旧、工程师的时间,都是成本。如果用例设计得不好,跑出来的结果要么覆盖不全,要么全是无效数据,那真是白忙活。

我个人习惯把测试用例设计分成三个层次:方法层(怎么想)、数据层(怎么选值)、时间层(怎么卡时序)。咱们一个一个来拆。

4.1 基于模型的测试方法

先说说基于模型的测试(MBT)。这玩意儿听起来高大上,其实说白了就是:用模型自动生成测试用例

我在项目中遇到过一种情况:一个BMS(电池管理系统)的SOC估算算法,状态机有十几个状态,手动写用例写到崩溃。后来我们用Simulink Stateflow建了个模型,让工具自动遍历所有状态转移路径,一下子生成了200多个测试用例。嗯,这里要注意,工具生成的用例不能直接用,你得加一些“业务直觉”进去过滤一遍。

MBT的核心流程,我总结为三步:

  1. 建模型:用状态机、活动图或时序图描述系统行为。我个人偏爱状态机,因为它跟HIL的“激励-响应”模式天然匹配。
  2. 选覆盖准则:比如状态覆盖、转移覆盖、路径覆盖。我建议从“状态覆盖”起步,别一上来就搞全路径,那会生成天文数字的用例。
  3. 生成并筛选:工具生成后,人工剔除那些“物理上不可能”的用例。比如,电机转速不可能从0直接跳到10000 rpm,中间得有加速过程。

重要提醒:MBT生成的用例,一定要跟HIL的实时性要求对齐。模型里一个状态转移可能只需要1ms,但HIL台架的IO刷新周期可能是10ms。这个差距不处理,用例跑出来全是时序违例。

4.2 等价类与边界值分析

接下来是经典但容易被忽视的等价类与边界值分析。很多工程师觉得这是软件测试的玩意儿,跟硬件在环没关系。其实恰恰相反——HIL测试里,输入信号的精度和范围,直接决定了测试的有效性

举个例子。你测试一个ADC采样通道,输入电压范围是0-5V。等价类划分很简单:

  • 有效等价类:0V ≤ Vin ≤ 5V
  • 无效等价类:Vin < 0V 或 Vin > 5V

但边界值呢?我建议你至少测这几个点:

边界类型 测试值 说明
下边界 0V, 0.01V 刚好在范围内和略高于下限
上边界 4.99V, 5.0V 刚好在范围内和达到上限
超下边界 -0.01V, -0.1V 略低于下限,看保护电路是否触发
超上边界 5.01V, 5.5V 略高于上限,看钳位或报警是否生效

我曾经在一次电机驱动器的HIL测试中,只测了0V和5V两个边界值,结果漏掉了4.99V这个点。量产之后发现,有个批次的ADC在4.98V时开始非线性漂移。嗯,从那以后,我再也不敢偷懒只测两个点了。

小技巧:对于HIL中的模拟量输入,边界值测试一定要加上“抖动”。比如,在边界值附近叠加一个±1%的正弦波扰动,看看系统是否误触发保护。这个我在多个项目中验证过,非常有效。

4.3 HIL场景的时序约束

最后,也是我认为最容易被忽略的——时序约束。HIL测试跟纯软件测试最大的区别,就是时间是真的在流逝。你写的测试脚本里,每一个delay、每一个等待,都对应着真实的物理时间。

我见过一个案例:测试团队写了一个HIL用例,要求CAN报文在100ms内响应。结果台架上跑的时候,因为上位机调度延迟,实际响应时间变成了105ms。测试报告显示“失败”,但其实是测试脚本的时序约束设得太死了。

所以,设计HIL场景的时序约束时,我建议遵循以下原则:

  1. 区分硬实时和软实时:硬实时约束(如安全气囊触发)必须严格满足,软实时约束(如仪表盘刷新)可以放宽。
  2. 加入时序裕量:我个人习惯在理论值基础上加20%的裕量。比如理论响应时间是80ms,我就设100ms为通过标准。
  3. 考虑台架本身的延迟:HIL台架的IO板卡、信号调理电路、上位机调度,都有延迟。你可以在测试前先跑一个“空跑”用例,测量台架本身的基线延迟。

这里给一个简单的时序约束示例,用Python伪代码表示:

# 时序约束示例:CAN报文响应测试
# 硬约束:必须在50ms内响应
# 软约束:建议在30ms内响应

HARD_TIMEOUT_MS = 50
SOFT_TIMEOUT_MS = 30

start_time = get_current_time_ms()
send_can_message("0x123", data)
response = wait_for_can_message("0x321", timeout=HARD_TIMEOUT_MS)

if response is None:
    test_fail("硬时序约束违例:未在50ms内收到响应")
elif response.time - start_time > SOFT_TIMEOUT_MS:
    test_warn("软时序约束超限:响应时间超过30ms,当前为{}ms".format(response.time - start_time))
else:
    test_pass("时序约束满足")

避坑指南:我曾经在测试一个ADAS(高级驾驶辅助系统)的紧急制动功能时,把时序约束设成了“从目标检测到制动指令输出不超过200ms”。结果台架上每次都失败,查了两天才发现——HIL台架的视觉仿真链路本身就有150ms的延迟。所以,一定要先标定台架自身的延迟,再设定被测对象的时序约束

好了,这一章的内容就这些。总结一下:基于模型的测试帮你解决“测什么”的问题,等价类与边界值分析帮你解决“测哪些值”的问题,时序约束帮你解决“什么时候测”的问题。三者结合,才能设计出真正有效的HIL测试用例。

下一章,我会聊聊测试脚本的编写与自动化执行。到时候见。