3. 测试环境搭建
在完成测试需求分析与覆盖率目标设定之后,下一步是把“要测什么”落到一个可执行、可复现的测试环境中。Simulink 提供的测试环境由三层构成:Simulink Test 提供测试编写与执行能力,Test Manager 提供测试用例、测试套件与结果的管理与批量执行能力,Test Harness 则提供被测模型与测试激励之间的隔离边界。三者配合,才能让测试既独立于模型内部实现,又不破坏原有模型结构。
一、测试环境的三层结构
理解这三层的关系,是搭建环境的前提。Simulink Test 是底层能力库,负责测试序列、评估、基线对比等;Test Manager 是上层管理界面,把多个测试文件、测试套件组织成可批量运行的集合,并统一保存测试结果;Test Harness 是模型侧的“测试外壳”,它把被测子系统从原模型中“摘”出来,单独提供输入端口、输出观测点和独立的求解器配置。
二、创建 Test Harness 的关键配置
Test Harness 的创建入口在 Simulink 中选中被测子系统后右键选择 Test Harness > Create for...。创建时最关键的三个配置项是:Harness 类型、源模型与 SUT 的引用方式、求解器与仿真配置。
Harness 类型通常选择 Inport/Outport 形式,即为被测子系统自动生成输入端口和输出端口,便于用 Signal Editor 或 From Workspace 注入激励。若被测对象是完整模型而非子系统,也可选择 Test Sequence 形式,直接在 Harness 内用测试序列驱动。
引用方式上,Harness 默认以“引用原模型中的子系统”方式工作,即 Harness 中的 SUT 块指向原模型里的同一子系统。这样做的优点是:原模型修改后 Harness 自动同步,无需手动重建;缺点是 Harness 不能独立于原模型存在。若需要完全隔离,可勾选 Create harness in a separate model,把 SUT 复制为独立副本,但此时需自行维护同步。
求解器配置建议与主模型保持一致,尤其是定步长与变步长的选择。若主模型使用定步长 Fixed-step、步长 0.01s,Harness 也应设为相同值,否则测试结果与集成仿真结果会出现偏差。对于需要精确事件触发的测试,可在 Harness 中单独设置 Zero-crossing detection 为 Enable all。
三、Test Manager 中的测试用例组织
Test Manager 的核心对象是 Test File 与 Test Suite。一个 Test File 对应一个 .mldatx 文件,内部可包含多个 Test Suite,每个 Suite 下可挂多个 Test Case。推荐的组织方式是:按被测功能模块划分 Test File,按测试类型(正常、边界、异常)划分 Test Suite,按具体场景划分 Test Case。
每个 Test Case 需要配置三部分:输入(激励信号或测试序列)、仿真设置(求解器、停止时间、Harness 选择)、评估(Assessment 或 Baseline)。以节气门位置控制为例,一个边界测试用例可配置为:输入阶跃信号从 0 到 100% 在 0.5s 内完成,仿真停止时间 2s,评估条件为“稳态误差 < 2% 且超调量 < 5%”。
% 示例:在 Test Manager 中以编程方式创建一个测试用例
tf = sltest.testmanager.TestFile('ThrottleCtrl_Test.mldatx');
ts = tf.getTestSuites();
tc = ts.addTestCase('Boundary_Step100');
tc.setProperty('Model', 'ThrottleCtrl_Harness');
tc.setProperty('StopTime', '2');
% 配置输入信号
tc.setInputSignal('Step_Input', 'Signal Editor', 'step_0to100.mat');
% 配置评估
tc.addAssessment('SteadyError', 'abs(SteadyState - 1.0) < 0.02');
tc.addAssessment('Overshoot', 'max(Response) < 1.05');
四、模型引用与测试隔离
当被测模型采用模型引用(Model Reference)方式组织时,测试隔离需要额外注意。模型引用会把子模型编译为独立的目标代码,Harness 若直接引用顶层模型,测试激励可能被顶层逻辑“截断”,无法直接作用到子模型。
正确的做法是:对需要独立测试的子模型单独创建 Harness,Harness 中的 SUT 块直接引用该子模型(而非顶层模型)。这样测试激励直接进入子模型输入端口,输出也直接从子模型输出端口观测,完全绕过顶层逻辑。若子模型有多个实例(同一子模型被多处引用),Harness 默认只针对其中一个实例,需在创建时指定 Instance 参数。
五、环境搭建的检查清单
| 检查项 | 预期状态 | 验证方式 |
|---|---|---|
| Harness 是否独立于原模型 | 原模型结构未变 | 对比创建前后模型差异 |
| 求解器配置是否一致 | 步长、类型与主模型相同 | 查看 Harness 的 Solver 配置 |
| Test Manager 能否识别 Harness | Test Case 中可选到 Harness 名称 | 在 Test Case 的 Model 下拉框中查看 |
| 激励信号是否可达 SUT | 仿真后 SUT 输入端口有数据 | 在 Harness 中加 Scope 观测 |
| 评估条件是否生效 | 测试结果中显示 Pass/Fail | 运行 Test Case 后查看结果 |
完成以上配置后,测试环境即具备“独立激励、独立观测、独立评估”的能力。此时再运行测试,得到的覆盖率数据才真正反映被测子系统的内部执行情况,而不是被顶层逻辑或其它子系统“稀释”后的结果。下一阶段即可在此基础上编写具体的测试用例并执行覆盖率采集。