2. Simulink模型可测试性设计
在覆盖率驱动的模型测试中,测试用例能否顺利编写、覆盖率能否被有效采集,很大程度上并不取决于测试工程师的技巧,而是取决于模型本身是否“可测试”。一个信号线全是 Signal1、Signal2,子系统层层嵌套且没有明确接口,关键中间量被封装在原子子系统内部的模型,即使功能完全正确,也会让测试工作举步维艰。本节围绕可测试性设计的五个抓手展开:信号线命名、子系统划分、测试点预留、接口规范化与可观测性设计。
一、信号线命名:让测试用例“看得懂”模型
信号线命名是可测试性设计中最基础、成本最低、收益最直接的一项。Simulink 默认给未命名信号分配 Signal1、Signal2 这类自动名称,它们在模型画布上看似无害,但在测试阶段会带来三个具体问题:其一,测试用例中的信号引用无法定位;其二,覆盖率报告中“未覆盖的分支”无法对应到具体物理量;其三,模型评审时无法判断某条信号是否应该被激励。
命名应遵循“物理量+单位+方向”的可读约定。例如一条表示车速的信号,命名为 VehSpd_kph 比 Speed 更明确;一条表示制动请求的信号,命名为 BrkReq_b 比 Brake 更能体现布尔语义。对于总线信号,建议采用 BusName.ElementName 的层级命名,使测试用例在 Signal Builder 或 Signal Editor 中可以直接按名称检索。命名完成后,应通过 Model Advisor 的“Check for unconnected lines and unlabeled signals”检查项批量筛查未命名信号,避免遗漏。
二、子系统划分:在“封装”与“可测”之间取平衡
子系统划分直接影响测试点的可达性。一个常见的误区是把功能相关的所有逻辑都塞进一个原子子系统,导致内部信号无法在仿真中被记录或强制赋值。可测试性设计建议按“功能边界”而非“代码行数”划分子系统,并遵循两条原则:
- 控制逻辑与执行机构分离:控制器输出(如
BrkCmd_Nm)与执行器模型(如制动器动力学)应位于不同子系统,便于在控制器输出端直接注入测试激励。 - 原子子系统仅用于需要代码生成的单元:若某子系统需要生成嵌入式代码,应设为原子子系统并配置
Function Packaging;若仅用于组织模型层次,应使用虚拟子系统,保持信号可穿透、可观测。
对于需要覆盖率统计的分支逻辑,应避免将其隐藏在 Enabled Subsystem 或 Triggered Subsystem 的使能端口之后,因为这类子系统的内部覆盖率采集需要额外的测试激励设计。若确实需要,应在测试计划中明确记录该子系统的使能条件。
三、测试点预留:为覆盖率采集留出“接口”
测试点预留的核心思想是:在模型设计阶段就为测试工程师预留可注入激励、可观测响应的节点。具体做法包括:
- 在关键信号线上添加
Test Point标记,并设置为“Input”或“Output”类型,使该信号在仿真中可被强制赋值或记录。 - 在控制器输出与执行器输入之间预留
Signal Conversion或Rate Transition模块,作为测试注入的物理断点。 - 对需要采集覆盖率的条件分支,确保其判断信号来自子系统外部,而非内部常量或参数。
测试点预留不是“越多越好”。过多的测试点会增加模型复杂度,并可能影响代码生成效率。建议只对以下三类节点预留测试点:安全关键信号、覆盖率目标中明确要求的分支条件、以及调试中反复需要观测的中间量。
四、接口规范化:让测试用例可复用
接口规范化要求模型的输入输出端口具有明确的类型、维度、采样时间和单位。在 Simulink 中,这体现为 Inport 和 Outport 模块的 Port Dimensions、Sample Time、Data Type 以及 Signal Attributes 中的 Unit 字段。一个规范化的接口应满足:
- 所有输入端口均有明确的
Data Type(如double、boolean、uint8),避免使用Inherit: auto。 - 采样时间与模型整体调度一致,避免在测试中因采样时间不匹配导致覆盖率异常。
- 端口名称与信号线命名规则一致,便于测试用例按名称引用。
接口规范化的直接收益是测试用例的可复用性。当模型接口稳定后,同一组测试用例可以在不同版本的模型上重复执行,覆盖率结果也具备可比性。
五、可观测性设计:让覆盖率“看得见”
可观测性是指测试工程师能否在不修改模型的前提下,观察到内部信号、状态和分支执行情况。Simulink 提供了多种可观测性手段:Signal Logging、Scope、To Workspace、Data Store Memory 以及覆盖率工具自身的 Coverage Recording。可测试性设计应确保:
- 关键中间信号已开启
Signal Logging,并设置合理的Logging Name。 - 覆盖率采集范围覆盖所有需要验证的子系统,而非仅顶层模型。
- 对于状态机(Stateflow),确保状态和转移均可被覆盖率工具识别。
下面这张图展示了可测试性设计五个抓手之间的关系:信号线命名与接口规范化是基础,子系统划分决定测试点的可达性,测试点预留与可观测性设计共同支撑覆盖率采集与测试用例编写。
六、一个可测试性检查清单
将上述五个抓手落到日常建模中,可以用一份检查清单来约束。以下清单可直接用于模型评审或提交测试前的自检:
| 检查项 | 合格标准 | 检查方式 |
|---|---|---|
| 信号线命名 | 无 SignalN 自动命名;关键信号含物理量与单位 |
Model Advisor 未命名信号检查 |
| 子系统划分 | 控制逻辑与执行机构分离;虚拟子系统优先 | 模型层次评审 |
| 测试点预留 | 安全关键信号与覆盖率目标分支有 Test Point | 信号属性检查 |
| 接口规范化 | 端口类型、维度、采样时间、单位均明确 | 端口属性批量检查 |
| 可观测性 | 关键中间信号开启 Signal Logging;覆盖率范围覆盖目标子系统 | 仿真日志与覆盖率报告核对 |
需要强调的是,可测试性设计不是要求模型“为测试而改”,而是让模型在保持功能正确的前提下,具备清晰的信号语义、合理的层次边界和可观测的内部节点。这五项工作做到位后,测试用例的编写将从“猜测信号含义”转变为“按接口规范构造激励”,覆盖率采集也将从“顶层黑盒”深入到“分支级白盒”,为后续的覆盖率验证与测试充分性评估打下可复现的基础。