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),确保状态和转移均可被覆盖率工具识别。

下面这张图展示了可测试性设计五个抓手之间的关系:信号线命名与接口规范化是基础,子系统划分决定测试点的可达性,测试点预留与可观测性设计共同支撑覆盖率采集与测试用例编写。

Simulink 可测试性设计五要素关系图 信号线命名 物理量+单位+方向,如 VehSpd_kph 接口规范化 类型/维度/采样时间/单位明确 子系统划分 功能边界划分,控制与执行分离 测试点预留 Test Point 标记,激励注入断点 可观测性设计 Signal Logging / 覆盖率采集范围 测试用例可编写 · 覆盖率可采集 · 结果可复现 基础层 结构层 测试层

六、一个可测试性检查清单

将上述五个抓手落到日常建模中,可以用一份检查清单来约束。以下清单可直接用于模型评审或提交测试前的自检:

检查项 合格标准 检查方式
信号线命名 无 SignalN 自动命名;关键信号含物理量与单位 Model Advisor 未命名信号检查
子系统划分 控制逻辑与执行机构分离;虚拟子系统优先 模型层次评审
测试点预留 安全关键信号与覆盖率目标分支有 Test Point 信号属性检查
接口规范化 端口类型、维度、采样时间、单位均明确 端口属性批量检查
可观测性 关键中间信号开启 Signal Logging;覆盖率范围覆盖目标子系统 仿真日志与覆盖率报告核对
可测试性设计的最佳介入时机是模型详细设计阶段,而非测试阶段。一旦模型进入集成测试,修改信号命名或调整子系统边界都会带来回归成本。建议在模型首次提交测试前,由建模工程师与测试工程师共同完成一次可测试性评审,评审输出即为上述检查清单的填写结果。

需要强调的是,可测试性设计不是要求模型“为测试而改”,而是让模型在保持功能正确的前提下,具备清晰的信号语义、合理的层次边界和可观测的内部节点。这五项工作做到位后,测试用例的编写将从“猜测信号含义”转变为“按接口规范构造激励”,覆盖率采集也将从“顶层黑盒”深入到“分支级白盒”,为后续的覆盖率验证与测试充分性评估打下可复现的基础。