Matlab Write Tests
MathWorksOfficialCreated by MathWorks
- Skill
- Content generator
- Software development
- BSD-2-Clause
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured approach to creating, organizing, and maintaining MATLAB unit tests. It focuses on class-based testing patterns, including parameterized tests, fixtures for setup and teardown, mocking dependencies, and programmatic UI testing for App Designer applications. It emphasizes robust testing practices such as the Arrange-Act-Assert pattern, floating-point tolerance handling, and baseline regression testing using MAT-file references.
What it does
- Generates class-based MATLAB unit test files
- Implements parameterized testing for efficient data-driven test cases
- Configures test fixtures for environment setup, teardown, and path management
- Simulates user interactions in App Designer using programmatic gestures
- Facilitates baseline and regression testing against stored reference data
- Provides patterns for mocking dependencies and ensuring test determinism
When to use it
- When writing new unit tests for MATLAB functions or classes
- When implementing test-driven development workflows
- When testing App Designer applications with UI gestures
- When creating regression tests against stored golden file data
- When needing to parameterize tests to reduce code duplication
Advantages
- Promotes clean, maintainable, and independent test code
- Ensures reproducible results through deterministic setup and teardown
- Supports complex testing scenarios like UI automation and dependency mocking
- Standardizes testing patterns across MATLAB projects
Usage examples
- “Write a class-based unit test for my function calculateVolume(radius, height) that includes a test for floating-point accuracy.”
- The agent generates a MATLAB class inheriting from matlab.unittest.TestCase, using verifyEqual with an AbsTol argument to handle floating-point precision.
- “How do I test my App Designer app's 'Run' button press?”
- The agent provides a test class inheriting from matlab.uitest.TestCase, demonstrating the use of the press() gesture and verification of the resulting UI state.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/matlab/matlab-write-tests/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip matlab-write-tests.zip -d .agents/skills
Documentation by MathWorks
Write Tests
Generate, structure, and organize MATLAB unit tests using the matlab.unittest and matlab.uitest frameworks.
When to Use
User asks to write tests for a MATLAB function or class
User wants to add test methods or parameterize existing tests
User needs fixtures, mocking, or dependency injection in tests
Test-driven development — writing tests before implementation
Testing App Designer apps with programmatic gestures
Baseline/regression tests against stored reference data (golden file, snapshot, characterization tests)
When NOT to Use
Running tests, analyzing failures, or filtering test suites — use
matlab-run-testsCollecting or analyzing code coverage — use
matlab-run-testsCI/CD pipeline configuration — use
matlab-run-testsTesting Simulink models — use Simulink test skills
Must-Follow Rules
Present a test plan first — For non-trivial test suites, propose test methods and edge cases for user approval before writing code
Always use class-based tests — Inherit from the appropriate TestCase superclass. Never use script-based tests
No logic in test methods — No
if,switch,for, ortry/catch. Follow Arrange-Act-Assert. If a test needs conditionals, split into separate methodsTest public interfaces, not implementation — Never test private methods directly
Execute via MCP — Use
run_matlab_test_fileorevaluate_matlab_codeto run tests after writing. For advanced test execution (coverage, filtering, CI), see thematlab-run-testsskill
Workflow
Simple tests (clear behavior, limited scope)
Briefly state what you'll test (methods + key edge cases)
Write the test file after user confirms
Run via
run_matlab_test_fileMCP tool to confirm tests pass
Standard tests (large codebase, multiple files)
Gather requirements — Code to test, expected behaviors, error conditions, scope, dependencies
Present test plan — List test methods, edge cases, parameterization strategy for approval
Implement — Write tests following the patterns below
Verify — Run via
run_matlab_test_fileMCP tool to confirm tests pass
Key Functions
| Category | Functions | Purpose |
|---|---|---|
| Equality | verifyEqual, verifyNotEqual | Compare values (use AbsTol for floats) |
| Boolean | verifyTrue, verifyFalse | Check logical conditions |
| Size/type | verifySize, verifyClass, verifyEmpty | Structural checks |
| Errors | verifyError | Confirm error is thrown with correct ID |
| Warnings | verifyWarning, verifyWarningFree | Check warning behavior |
Qualification Levels
| Level | On failure | When to use |
|---|---|---|
verify | Continues test | Default — most assertions |
assert | Stops current test | Setup validation |
fatalAssert | Stops entire suite | Environment preconditions |
assume | Skips test | Conditional execution (e.g., toolbox check) |
Patterns
Basic Test Class
classdef computeAreaTest < matlab.unittest.TestCase
methods (Test)
function testSquare(testCase)
result = computeArea(5, 5);
testCase.verifyEqual(result, 25);
end
function testFloatingPoint(testCase)
result = computeArea(1/3, 3);
testCase.verifyEqual(result, 1, AbsTol=1e-12);
end
function testNegativeInputErrors(testCase)
testCase.verifyError( ...
@() computeArea(-1, 5), 'computeArea:negativeInput');
end
end
endParameterized Tests
Parameterize only when assertion logic is identical across all cases — only the data varies. Use struct for readable test names:
classdef unitConverterTest < matlab.unittest.TestCase
properties (TestParameter)
conversionCase = struct( ...
'freezing', struct('input', 0, 'expected', 32), ...
'boiling', struct('input', 100, 'expected', 212), ...
'bodyTemp', struct('input', 37, 'expected', 98.6));
end
methods (Test)
function testCelsiusToFahrenheit(testCase, conversionCase)
result = celsiusToFahrenheit(conversionCase.input);
testCase.verifyEqual(result, conversionCase.expected, AbsTol=1e-10);
end
end
endError testing — identical verifyError logic, only inputs and error IDs vary:
properties (TestParameter)
InvalidInput = struct( ...
'zeroDivisor', struct('input', {{5, 0}}, 'errorId', 'fn:zeroDivisor'), ...
'stringArg', struct('input', {{'hello', 1}}, 'errorId', 'fn:nonNumeric'), ...
'cellArg', struct('input', {{{1}, 2}}, 'errorId', 'fn:nonNumeric'))
end
methods (Test)
function testInvalidInputThrows(testCase, InvalidInput)
testCase.verifyError(@() fn(InvalidInput.input{:}), InvalidInput.errorId);
end
endFor advanced parameterization (combinations, dynamic parameters, ClassSetupParameter), see references/parameterized-tests-guidance.md.
Setup, Teardown, and Fixtures
Prefer addTeardown over TestMethodTeardown blocks. Use PathFixture to add source folders:
classdef fileProcessorTest < matlab.unittest.TestCase
methods (TestClassSetup)
function addSourceToPath(testCase)
srcFolder = fullfile(fileparts(fileparts(mfilename('fullpath'))), 'src');
testCase.applyFixture(matlab.unittest.fixtures.PathFixture(srcFolder, ...
IncludingSubfolders=true));
end
end
methods (Test)
function testProcessFile(testCase)
tmpDir = string(tempname);
mkdir(tmpDir);
testCase.addTeardown(@() rmdir(tmpDir, 's'));
testFile = fullfile(tmpDir, "data.csv");
writematrix(rand(10, 3), testFile);
result = processFile(testFile);
testCase.verifySize(result, [10 3]);
end
end
endFor built-in fixtures, custom fixtures, and shared fixtures, see references/fixtures-guidance.md.
Determinism
Seed the RNG and restore it in teardown for reproducible tests:
methods (TestMethodSetup)
function resetRandomSeed(testCase)
originalRng = rng;
testCase.addTeardown(@() rng(originalRng));
rng(42, "twister");
end
endTest Tags
Use TestTags for selective execution:
methods (Test, TestTags = {'Unit'})
function testFastCalculation(testCase)
% ...
end
end
methods (Test, TestTags = {'Integration', 'Slow'})
function testFullPipeline(testCase)
% ...
end
endApp Designer Testing
For testing apps with programmatic UI gestures (press, choose, type, drag), see references/app-testing-guidance.md.
Key points:
Inherit from
matlab.uitest.TestCase(notmatlab.unittest.TestCase)Call
drawnowafter app creation, before first gestureCompare
uilabel.Textwith char ('text'), not string ("text")Compare
.Enablewithmatlab.lang.OnOffSwitchState.on/.off
Baseline Tests
For baseline, regression, gold-file, snapshot, or characterization tests, use matlabtest.parameters.matfileBaseline + verifyEqualsBaseline (requires MATLAB Test, R2024b+) instead of hardcoding expected values or manually loading reference data.
Workflow
Define parameterization — One
TestParameterproperty per baseline value, usingmatlabtest.parameters.matfileBaselinewithVariableName. Consolidate related baselines into a single MAT file.Write test methods — Each method accepts the baseline parameter and calls
verifyEqualsBaseline. PassAbsTolorRelTolfor floating-point tolerance.Generate baseline data — Run the function under test, save results to the baseline MAT file.
Run tests — Execute the test file to confirm actual values match baselines.
properties (TestParameter)
result = matlabtest.parameters.matfileBaseline( ...
"baselines/output.mat", VariableName="result")
end
methods (Test)
function testOutput(testCase, result)
actual = myFunction(inputData);
testCase.verifyEqualsBaseline(actual, result);
end
endNever use verifyEqual with hardcoded or manually-computed expected values for baseline/regression/gold-file tests. Always use matfileBaseline + verifyEqualsBaseline — even when tolerance is needed (pass AbsTol/RelTol to verifyEqualsBaseline).
Store baselines in baselines/ relative to the test file. For detailed patterns, multiple-variable consolidation, and baseline generation, see references/baseline-tests-guidance.md.
References
Load these on demand — most tests only need what's in this file.
| Load when... | Reference |
|---|---|
| Tests need setup/teardown, temp dirs, path management, shared state | references/fixtures-guidance.md |
| Floating-point tolerance selection, constraint objects, custom constraints | references/constraints-guidance.md |
| Multiple parameters, dynamic parameters, combination strategies | references/parameterized-tests-guidance.md |
| Code depends on external services, needs mock objects or dependency injection | references/mocking-guidance.md |
| Testing App Designer apps with gestures, dialogs, async callbacks | references/app-testing-guidance.md |
| Baseline/regression tests against stored reference data, golden file tests | references/baseline-tests-guidance.md |
Conventions
Always use class-based tests inheriting from
matlab.unittest.TestCaseName test files
<functionName>Test.mand place intests/directoryUse
verifyqualifications by default — they let all tests run even if one failsUse
AbsTolfor every floating-point comparison — never rely on exact equalityNo logic in test methods — follow Arrange-Act-Assert
Use
addTeardownfor cleanup — it runs even if the test failsUse struct-based
TestParameterfor readable parameterized test namesPrefer: parameterized error testing over repeated methods when multiple inputs trigger the same verifyError pattern
Keep test methods focused — test one behavior per method
Tests must be independent and compatible with parallel execution
Run tests via the
run_matlab_test_fileMCP tool for automatic result capture
Copyright 2026 The MathWorks, Inc.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.0 KiB
- LICENSELicence file added by AutoGineer1.4 KiB
- SKILL.md11.2 KiB
- manifest.yaml495 B
- references/app-testing-guidance.md7.3 KiB
- references/baseline-tests-guidance.md6.0 KiB
- references/constraints-guidance.md2.2 KiB
- references/fixtures-guidance.md2.7 KiB
- references/mocking-guidance.md3.3 KiB
- references/parameterized-tests-guidance.md3.6 KiB
references/app-testing-guidance.md
App Designer Testing
Test MATLAB App Designer applications programmatically using matlab.uitest.TestCase, which simulates real user interactions — button presses, dropdown selections, text entry, slider drags — and verifies app behavior.
Workflow
Inspect the app — Read the app class to identify components, callbacks, and testable behavior
Design test cases — Map each user workflow to a test method (arrange state, perform gestures, verify outcome)
Create the test class — Inherit from
matlab.uitest.TestCase, launch the app inTestMethodSetupwithaddTeardownfor cleanupWrite gesture sequences — Simulate user actions using
matlab.uitest.TestCasegesture methods (see Key Functions below)Verify outcomes — Assert on component values, visibility, plot data, table contents, or app properties
Run and iterate — Execute via
run_matlab_test_file, fix failures, add edge cases
Key Functions
| Category | Functions |
|---|---|
| Test base class | matlab.uitest.TestCase |
| Gesture — click | press(tc, comp) — buttons, switches, state buttons, spinners, axes |
| Gesture — select | choose(tc, comp, option) — dropdowns, list boxes, knobs, tabs, sliders, table cells |
| Gesture — text | type(tc, comp, value) — edit fields, text areas, table cells |
| Gesture — drag | drag(tc, comp, start, stop) — sliders, knobs, axes |
| Gesture — hover | hover(tc, comp), hover(tc, comp, location) — axes, figures |
| Gesture — scroll | scroll(tc, comp, direction) — axes, figures (R2024a+) |
| Context menus | chooseContextMenu(tc, comp, menuItem) — right-click menus (R2020b+) |
| Dialog — dismiss | dismissDialog(tc, dialogType, fig) — close alert dialogs (R2024b+) |
| Dialog — choose | chooseDialog(tc, dialogType, fig, option) — select dialog option (R2024b+) |
| Figure unlock | matlab.uitest.unlock(fig) — unlock figure for manual interaction after test |
| Interactive use | matlab.uitest.TestCase.forInteractiveUse — ad-hoc testing at command window |
Patterns
Test Class Structure
Every app test class follows this pattern: store the app in a property, launch in TestMethodSetup with addTeardown for cleanup, interact via gestures in test methods. The app name (MyApp), component names (RunButton, StatusLabel), and expected values ('Ready') in the example below are example-specific — substitute with the actual app under test.
classdef MyAppTest < matlab.uitest.TestCase
properties (Access = private)
App
end
methods (TestMethodSetup)
function launchApp(testCase)
testCase.App = MyApp();
testCase.addTeardown(@delete, testCase.App);
drawnow;
end
end
methods (Test)
function testDefaultState(testCase)
testCase.verifyEqual(testCase.App.StatusLabel.Text, 'Ready');
end
function testButtonPress(testCase)
press(testCase, testCase.App.RunButton);
testCase.verifyEqual(testCase.App.StatusLabel.Text, 'Running...');
end
end
endAccessing App Components
The test needs handles to UI components. How you get them depends on the app architecture:
% Pattern A: App exposes components as public properties
app = MyApp();
press(testCase, app.RunButton);
% Pattern B: If components are private, make them public for testability.
% App Designer components should be accessible via public properties
% so tests can interact with them directly. Avoid friend-class access
% or testing private implementation details.
% Pattern C: Find components by type/tag from the figure
fig = app.UIFigure;
btns = findobj(fig, 'Type', 'uibutton', 'Text', 'Run');
press(testCase, btns(1));Verifiable Component Properties
| What to check | Access pattern |
|---|---|
| Field value | app.EditField.Value |
| Label text | app.Label.Text |
| Button/component enabled | app.Button.Enable |
| Dropdown items | app.DropDown.Items |
| Dropdown selection | app.DropDown.Value |
| Table data | app.Table.Data |
| Panel visibility | app.Panel.Visible |
| Plot line data | findobj(app.UIAxes, 'Type', 'Line') → .XData, .YData |
| Image presence | findobj(app.UIAxes, 'Type', 'Image') |
Dialog Handling (R2024b+)
function testConfirmSave(testCase)
% Press a button that triggers a uiconfirm dialog, then accept it
press(testCase, app.SaveButton);
chooseDialog(testCase, "uiconfirm", app.UIFigure, "Yes");
testCase.verifyEqual(app.StatusLabel.Text, 'Saved');
end
function testDismissAlert(testCase)
% Trigger an alert and dismiss it
press(testCase, app.ValidateButton);
dismissDialog(testCase, "uialert", app.UIFigure);
end
% For blocking dialogs, pass the triggering action as a function handle
function testBlockingConfirm(testCase)
chooseDialog(testCase, "uiconfirm", app.UIFigure, ...
@() press(testCase, app.DeleteButton), "OK");
endTesting Async / Long-Running Callbacks
function testAsyncAnalysis(testCase)
press(testCase, app.AnalyzeButton);
% Wait for callback to complete (poll with timeout)
maxWait = 10; % seconds
elapsed = 0;
while app.StatusLabel.Text ~= "Complete" && elapsed < maxWait
pause(0.5);
drawnow;
elapsed = elapsed + 0.5;
end
testCase.verifyEqual(app.StatusLabel.Text, 'Complete', ...
'Analysis did not complete within timeout');
endType-Matching Pitfalls
UI component properties do not always return the types you expect. These mismatches cause verifyEqual failures:
| Property | Returns | Wrong comparison | Correct comparison |
|---|---|---|---|
uilabel.Text | char | verifyEqual(lbl.Text, "Ready") | verifyEqual(lbl.Text, 'Ready') |
comp.Enable | matlab.lang.OnOffSwitchState | verifyEqual(btn.Enable, 'on') | verifyEqual(btn.Enable, matlab.lang.OnOffSwitchState.on) |
uidropdown.Value | char or string (depends on Items type) | — | Cast with string() if comparing against string literals |
Recommended pattern for Enable checks — define constants to avoid verbose enum names:
properties (Constant, Access = private)
ON = matlab.lang.OnOffSwitchState.on
OFF = matlab.lang.OnOffSwitchState.off
end
% Then in tests:
testCase.verifyEqual(app.RunButton.Enable, testCase.ON);Conventions
Inherit from
matlab.uitest.TestCase, notmatlab.unittest.TestCaseFigures must be visible — never set
'Visible', 'off'on the test figureCall
drawnowafter app creation and before the first gestureLaunch a fresh app per test in
TestMethodSetupto avoid cross-test contaminationUse
testCase.addTeardown(@delete, app)immediately after launching the app to ensure cleanup even if the test fails. Prefer this over a separateTestMethodTeardownblockAccess components via public properties; use
findobjas a fallback for private componentsCompare label
.Textwith char ('text'), not string ("text")Compare
.Enablewithmatlab.lang.OnOffSwitchState.on/.off, not'on'/'off'For apps with long callbacks, poll with
pause/drawnowand a timeout — never use a fixedpausealone
Copyright 2026 The MathWorks, Inc.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- MathWorks
- Publisher
- MathWorks (Official)
- Source
- matlab/matlab-agentic-toolkit · skills-catalog/matlab-software-development/matlab-write-tests · commit 2a7f215
- Licence
- BSD 2-Clause License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.md)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by MathWorks or MathWorks.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download matlab-write-tests.zip