# 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.

- Skill: `thedixitjain/simulink-baseline-test` (Agent Skill)
- Install (CLI): `npx skillmds add thedixitjain/simulink-baseline-test`
- Raw SKILL.md: https://api.skillmd.com/api/skills/thedixitjain/simulink-baseline-test/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: thedixitjain (https://skillmd.com/u/thedixitjain)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/thedixitjain/simulink-baseline-test

---



# Simulink Baseline Test Creation

Creates a MATLAB test class that captures and validates Simulink model outputs against a saved baseline.

## Workflow

### Step 1: Analyze the Model

Resolve the model name and explore its structure to select 2–5 signals representative of the model's key behavior.

```matlab
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.

### Step 2: Configure Signal Logging

Enable logging on selected output ports:

```matlab
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.

### Step 3: Capture Baseline

Simulate and save the full `logsout` Dataset — not individual timeseries:

```matlab
in = Simulink.SimulationInput(modelName);
out = sim(in);

baselineLogsout = out.logsout;
save(fullfile(modelDir, 'baselineData.mat'), 'baselineLogsout');
```

### Step 4: Write the Test Class

Follow these mandatory conventions:

#### Inherit from `sltest.TestCase`

```matlab
classdef MyModelBaselineTest < sltest.TestCase
```

Not `matlab.unittest.TestCase`. This gives access to `verifySignalsMatch`.

#### Single simulation, single comparison

Simulate the model **once**. Compare **all** signals in one call using `verifySignalsMatch`:

```matlab
testCase.verifySignalsMatch(out.logsout, S.baselineLogsout, ...
    'RelTol', testCase.RelTol, ...
    'AbsTol', testCase.AbsTol);
```

**Never** loop through individual signals. **Never** simulate once per signal.

#### Use `RelTol` and `AbsTol` directly

Pass `'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`).

#### Smart model teardown with `bdIsLoaded`

Only close the model if it was not already loaded before the test:

```matlab
wasLoaded = bdIsLoaded(testCase.ModelName);
load_system(testCase.ModelName);
if ~wasLoaded
    testCase.addTeardown(@()close_system(testCase.ModelName, 0));
end
```

#### Do NOT manually run `PreLoadFcn`

`load_system` automatically triggers the model's `PreLoadFcn` callback. Never call `evalin('base', get_param(model, 'PreLoadFcn'))`.

#### Include a static `generateBaseline()` method

For easy re-baselining after intentional changes:

```matlab
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
```

### Step 5: Run and Verify

Execute the test and confirm all signals match:

```matlab
results = runtests('MyModelBaselineTest');
```

## Complete Test Class Template

```matlab
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
```

## Anti-Patterns — Do NOT

- **Simulate once per signal** (parameterized tests calling `sim` each time)
- **Loop through signals** to verify individually — use `verifySignalsMatch`
- **Manually scale tolerances** (`max(abs(data)) * relTol`) — use `'RelTol'` directly
- **Save individual timeseries** — save the full `logsout` Dataset
- **Unconditionally close the model** — check `bdIsLoaded` first
- **Manually call `PreLoadFcn`** — `load_system` handles it
- **Use `matlab.unittest.TestCase`** — use `sltest.TestCase` for `verifySignalsMatch`

---

**Source:** [`hashgraph-online/awesome-codex-plugins`](https://github.com/hashgraph-online/awesome-codex-plugins) → `plugins/summer521521/MATLAB_Simulink_plugin/skills/simulink-baseline-test/SKILL.md`

