4. SIL基础概念与工程定位

MIL(Model-in-the-Loop)自动化测试,说白了就是把原来人工点鼠标的测试工作,交给脚本和工具去跑。我刚开始做MIL测试那会儿,还傻乎乎地一个个模型双击、一个个信号对。后来项目一多,版本一迭代,才发现手工测试根本扛不住。嗯,自动化是唯一的路。

这一章,我带你走一遍MIL自动化的三个核心环节:脚本编写、Test Manager操作、报告生成。这三件事串起来,就是一条完整的自动化流水线。

4.1 为什么MIL必须自动化?

你想想看,一个中等规模的车控模型,测试用例少说几百条。如果每次模型改个参数、加个功能,都要手动跑一遍,那项目周期就别想控住了。更麻烦的是,手动操作容易漏测、误判,出了问题回溯起来也费劲。

自动化的好处很直接:

  • 可重复:同样的用例,每次跑结果一致
  • 可追溯:谁跑的、什么时候跑的、结果怎样,一清二楚
  • 可集成:能挂到CI/CD流水线上,模型一更新就自动触发测试

核心观点:MIL自动化的本质,是把“人盯着模型看”变成“脚本替人检查结果”。你只需要定义好“什么是对的”,剩下的交给工具。

4.2 MATLAB脚本编写:从手动到自动的第一步

我个人习惯,先写一个基础的测试脚本框架。这个框架包含三个部分:模型加载、信号注入、结果采集。

下面是一个最简单的例子,用来测试一个PID控制器的阶跃响应:

%% 1. 加载模型
modelName = 'PID_Controller_MIL';
load_system(modelName);

%% 2. 设置输入信号
t = 0:0.01:10;
inputSignal = [t', ones(length(t),1)];  % 阶跃信号

%% 3. 运行仿真
simOut = sim(modelName, 'SimulationMode', 'normal', ...
             'StopTime', '10', ...
             'SaveOutput', 'on', ...
             'OutputSaveName', 'yout');

%% 4. 提取结果
y = simOut.yout.signals(1).values;
t_sim = simOut.tout;

%% 5. 自动判据
overshoot = (max(y) - y(end)) / y(end) * 100;
if overshoot < 5
    disp('超调量合格');
else
    error('超调量超标:%.2f%%', overshoot);
end

%% 6. 清理
bdclose(modelName);

这段脚本看起来简单,但我在项目中遇到过一个问题:模型路径写死了。后来换了个目录,脚本就报错。我建议你把模型路径、参数配置都抽成变量,或者用which函数动态查找。

小技巧:用Simulink.SimulationInput对象来管理仿真参数,比直接传参更灵活。你可以预先配置多组参数,然后批量跑。

4.3 Test Manager工具:把脚本组织成测试套件

脚本写好了,但总不能每次都手动敲命令吧?MATLAB的Test Manager就是干这个的。它能把你的脚本、模型、测试用例组织成一个可视化的测试工程。

我常用的操作流程是这样的:

  1. 创建测试文件:在Test Manager里新建一个.mldatx文件
  2. 添加测试套件:按功能模块分组,比如“加速测试”、“制动测试”
  3. 关联脚本:每个测试用例绑定一个MATLAB脚本或Simulink Test迭代
  4. 设置参数:定义输入信号、仿真时长、容差范围
  5. 执行测试:点一下Run,或者用命令行runTests触发

下面这张图展示了Test Manager里的测试结构:

Test Manager 测试结构 测试文件 (.mldatx) 套件A:加速测试 套件B:制动测试 套件C:转向测试 TC001:急加速 TC002:缓加速 TC003:紧急制动 TC004:点刹 TC005:左转极限 TC006:右转回正 说明 • 每个测试套件可以包含多个测试用例 • 测试用例可以关联MATLAB脚本、Simulink Test迭代或Excel数据 • 支持参数化测试:同一用例用不同参数跑多次

Test Manager还有一个很实用的功能——参数化测试。比如你要测不同车速下的制动距离,不用写10个脚本,只需要定义一个参数范围,工具会自动展开成多个测试用例。

注意:Test Manager的迭代模式(Iteration)和脚本模式(Script)不要混用。迭代模式适合参数扫描,脚本模式适合复杂逻辑判断。我见过有人把迭代逻辑写在脚本里,结果跑起来又慢又难维护。

4.4 测试报告自动生成:让结果说话

测试跑完了,结果得让人看得懂。手动截图、贴数据?太原始了。MATLAB提供了测试报告生成器,可以一键生成PDF或HTML报告。

我常用的报告生成方式有两种:

方式 适用场景 优点 缺点
Test Manager内置导出 快速查看、临时汇报 操作简单,无需写代码 格式固定,定制性差
MATLAB Report Generator 自动化流水线、客户交付 完全自定义,可嵌入图表 需要学习模板语法

如果你用Report Generator,代码大概长这样:

%% 创建报告对象
import mlreportgen.report.*
rpt = Report('MIL_Test_Report', 'pdf');

%% 添加章节
ch1 = Chapter('测试概述');
add(rpt, ch1);

p1 = Paragraph('本次测试覆盖了加速、制动、转向三个模块,共执行用例12个。');
add(ch1, p1);

%% 添加结果表格
tbl = Table({'用例ID', '状态', '超调量', '结论'; ...
             'TC001', '通过', '3.2%', '合格'; ...
             'TC002', '通过', '1.8%', '合格'; ...
             'TC003', '失败', '8.7%', '超调超标'});
add(ch1, tbl);

%% 添加波形图
fig = figure('Visible', 'off');
plot(t_sim, y);
title('TC001 阶跃响应曲线');
img = Image(sprintf('%s.png', tempname));
print(fig, img.Path, '-dpng');
add(ch1, img);

%% 生成报告
close(rpt);
rptview(rpt);

这段代码生成一份带表格和波形的PDF报告。我在项目中遇到过一个问题:波形图分辨率太低。后来我加了-r300参数,图片才清晰起来。

建议:报告里除了“通过/失败”,一定要附上关键波形和判据边界。这样评审的时候,别人一眼就能看出问题出在哪,不用再回头翻模型。

4.5 自动化流水线的完整拼图

把上面三块拼起来,就是一条完整的MIL自动化测试流水线:

  1. 脚本层:定义测试逻辑、判据、数据采集
  2. 组织层:用Test Manager管理用例、参数、执行顺序
  3. 报告层:自动生成文档,存档或发送邮件

我曾经帮一个团队搭过这套流水线。刚开始他们觉得“写脚本太麻烦”,后来模型迭代了三个版本,手工测试的人累得不行,自动化测试那边点一下按钮就出结果。嗯,从那以后,没人再提手工测试的事了。

一句话总结:MIL自动化测试不是“要不要做”的问题,而是“怎么做才高效”的问题。脚本、Test Manager、报告生成,这三样东西你玩熟了,MIL阶段就能做到“一键测试,自动出报告”。