协作头脑风暴
brainstorming
在实现前澄清需求、探索设计选择,并形成清晰的开发方向。
simulink-baseline-test【开发与工程】Create a MATLAB baseline regression test class for a Simulink model. Use when asked to create a baseline test, golden-reference test, or regression test for a Simulink model.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Creates a MATLAB test class that captures and validates Simulink model outputs against a saved baseline.
Resolve the model name and explore its structure to select 2–5 signals representative of the model's key behavior.
modelName = bdroot(gcs);
% List top-level subsystems
opts = Simulink.FindOptions;
opts.SearchDepth = 1;
topBlocks = getfullname(Simulink.findBlocks(modelName, opts));
for i = 1:numel(topBlocks)
bt = get_param(topBlocks{i}, 'BlockType');
fprintf(' [%s] %s\n', bt, topBlocks{i});
end
Explore subsystem ports, bus selectors, scopes, and outports to understand signal flow. Look for signals that best represent the model's overall behavior — plant outputs, actuator commands, sensor readings, or any other meaningful quantities.
Enable logging on selected output ports:
ph = get_param('<block path>', 'PortHandles');
set(ph.Outport(1), 'DataLogging', 'on');
set(ph.Outport(1), 'Name', '<signalName>');
Never use To Workspace blocks for signal capture.
Simulate and save the full logsout Dataset — not individual timeseries:
in = Simulink.SimulationInput(modelName);
out = sim(in);
baselineLogsout = out.logsout;
save(fullfile(modelDir, 'baselineData.mat'), 'baselineLogsout');
Follow these mandatory conventions:
sltest.TestCaseclassdef MyModelBaselineTest < sltest.TestCase
Not matlab.unittest.TestCase. This gives access to verifySignalsMatch.
Simulate the model once. Compare all signals in one call using verifySignalsMatch:
testCase.verifySignalsMatch(out.logsout, S.baselineLogsout, ...
'RelTol', testCase.RelTol, ...
'AbsTol', testCase.AbsTol);
Never loop through individual signals. Never simulate once per signal.
RelTol and AbsTol directlyPass 'RelTol' and 'AbsTol' as name-value arguments. MATLAB applies RelTol element-wise per sample; AbsTol acts as a floor for values near zero. Never manually scale tolerances (e.g., max(abs(data)) * relTol).
bdIsLoadedOnly close the model if it was not already loaded before the test:
wasLoaded = bdIsLoaded(testCase.ModelName);
load_system(testCase.ModelName);
if ~wasLoaded
testCase.addTeardown(@()close_system(testCase.ModelName, 0));
end
PreLoadFcnload_system automatically triggers the model's PreLoadFcn callback. Never call evalin('base', get_param(model, 'PreLoadFcn')).
generateBaseline() methodFor easy re-baselining after intentional changes:
methods (Static)
function generateBaseline()
modelName = MyModelBaselineTest.ModelName;
load_system(modelName);
in = Simulink.SimulationInput(modelName);
out = sim(in);
baselineLogsout = out.logsout; %#ok<NASGU>
save(MyModelBaselineTest.BaselineFile, 'baselineLogsout');
close_system(modelName, 0);
end
end
Execute the test and confirm all signals match:
results = runtests('MyModelBaselineTest');
classdef MyModelBaselineTest < sltest.TestCase
properties (Constant)
ModelName = 'MyModel'
BaselineFile = fullfile(fileparts(mfilename('fullpath')), 'baselineData.mat')
RelTol = 1e-6
AbsTol = 1e-8
end
methods (TestClassSetup)
function loadModelAndBaseline(testCase)
wasLoaded = bdIsLoaded(testCase.ModelName);
load_system(testCase.ModelName);
if ~wasLoaded
testCase.addTeardown(@()close_system(testCase.ModelName, 0));
end
testCase.assertTrue(isfile(testCase.BaselineFile), ...
sprintf('Baseline not found: %s\nRun %s.generateBaseline() first.', ...
testCase.BaselineFile, mfilename('class')));
end
end
methods (Test)
function testAllSignalsMatchBaseline(testCase)
in = Simulink.SimulationInput(testCase.ModelName);
out = sim(in);
S = load(testCase.BaselineFile, 'baselineLogsout');
testCase.verifySignalsMatch(out.logsout, S.baselineLogsout, ...
'RelTol', testCase.RelTol, ...
'AbsTol', testCase.AbsTol);
end
end
methods (Static)
function generateBaseline()
modelName = MyModelBaselineTest.ModelName;
load_system(modelName);
in = Simulink.SimulationInput(modelName);
out = sim(in);
baselineLogsout = out.logsout; %#ok<NASGU>
save(MyModelBaselineTest.BaselineFile, 'baselineLogsout');
fprintf('Baseline saved to: %s\n', MyModelBaselineTest.BaselineFile);
close_system(modelName, 0);
end
end
end
sim each time)verifySignalsMatchmax(abs(data)) * relTol) — use 'RelTol' directlylogsout DatasetbdIsLoaded firstPreLoadFcn — load_system handles itmatlab.unittest.TestCase — use sltest.TestCase for verifySignalsMatch