Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,35 @@ covPlugin = matlab.unittest.plugins.CodeCoveragePlugin.forFolder("code", "Produc
obj = examplesTester(["examples", "doc"], CodeCoveragePlugin = covPlugin);
obj.executeTests;
```
## Integration with MATLAB's BuildTool
From MATLAB R2025a and onwards, users can use the `ExampleDrivenTesterTask`, a ready-to-use buildtool task shipped with ExamplesDrivenTester for automated example testing.

When you install the toolbox in MATLAB R2025a+, you'll automatically get this pre-configured task that you can use directly in your build files.

### Usage Examples
Add the **ExamplesDrivenTester** task to your buildfile.m using the following patterns:

1. Run MATLAB scripts from specified folders and generate a test report (default behavior):
```matlab
plan("runExample") = ExampleDrivenTesterTask(["examples", "doc"]);
```

2. Run MATLAB scripts but do NOT generate a test report:
```matlab
plan("runExample") = ExampleDrivenTesterTask(["examples", "doc"], CreateTestReport = false);
```

3. Run MATLAB scripts and generate a test report in PDF format:
```matlab
plan("runExample") = ExampleDrivenTesterTask(["examples", "doc"], TestReportFormat = "pdf");
```
4. Run MATLAB scripts and generate a code coverage report for code placed in the code folder:
```matlab

reportFormat = matlab.unittest.plugins.codecoverage.CoverageReport('coverage-report');
covPlugin = matlab.unittest.plugins.CodeCoveragePlugin.forFolder("code", "Producing", reportFormat);
plan("runExample") = ExampleDrivenTesterTask(["examples", "doc"], CodeCoveragePlugin = covPlugin);
```

## License

Expand Down
8 changes: 8 additions & 0 deletions buildfile.m
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
function plan = buildfile
import matlab.buildtool.tasks.CodeIssuesTask
import matlab.buildtool.tasks.TestTask
import matlab.buildtool.tasks.CleanTask

% Create a plan from task functions
plan = buildplan(localfunctions);

% Add a task to identify code issues
plan("check") = CodeIssuesTask;

plan("clean") = CleanTask;

plan("test") = TestTask('./tests');

% Run MATLAB scripts from specified folder and generate a code coverage report
reportFormat = matlab.unittest.plugins.codecoverage.CoverageReport('coverage-report');
covPlugin = matlab.unittest.plugins.CodeCoveragePlugin.forFolder("toolbox/sampleToolbox/code", "Producing", reportFormat);
plan("runExample") = ExampleDrivenTesterTask("toolbox/sampleToolbox/examples", CodeCoveragePlugin = covPlugin);

plan.DefaultTasks = "test";

end
Expand Down
81 changes: 81 additions & 0 deletions toolbox/internal/ExampleDrivenTesterTask.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
classdef ExampleDrivenTesterTask < matlab.buildtool.Task
% Buildtool task to run example scripts with optional test & coverage reports.
% Inputs:
% - Folders: string array of M-script locations
% Optional Inputs:
% - CreateTestReport (logical)
% - TestReportFormat (string)
% - ReportOutputFolder (string)
% - CodeCoveragePlugin (object)

properties
Folders (1,:) string
CreateTestReport (1,1) logical = true
TestReportFormat (1,1) string = "HTML"
OutputPath (1,1) string = "test-report"
CodeCoveragePlugin = []
end

methods
function task = ExampleDrivenTesterTask(folders, options)
% Constructor
arguments
folders (1,:) string
options.CreateTestReport (1,1) logical = true
options.TestReportFormat (1,1) string = "html"
options.OutputPath(1,1) string = "test-report"
options.CodeCoveragePlugin = []
end

task.Description = "Run published examples";
task.Inputs = folders;

% Basic validation
mustBeMember(options.TestReportFormat, ["html", "pdf", "docx", "xml"]);
for f = folders
if ~isfolder(f)
error("ExampleDrivenTesterTask:FolderNotFound", ...
"Folder not found: %s", f);
end
end

task.Folders = folders;
task.CreateTestReport = options.CreateTestReport;
task.TestReportFormat = options.TestReportFormat;
task.OutputPath= options.OutputPath;
task.CodeCoveragePlugin= options.CodeCoveragePlugin;

if task.CreateTestReport
task.Outputs = task.OutputPath;
else
task.Outputs = string.empty;
end
end
end

methods (TaskAction, Sealed, Hidden)

function runExampleTests(task, ~)
if task.CreateTestReport && ~isfolder(task.OutputPath)
mkdir(task.OutputPath);
end

if isempty(task.CodeCoveragePlugin)
obj = examplesTester( ...
task.Folders, ...
CreateTestReport = task.CreateTestReport, ...
TestReportFormat = task.TestReportFormat, ...
OutputPath = task.OutputPath);
else
% Pass CodeCoveragePlugin through when provided
obj = examplesTester( ...
task.Folders, ...
CreateTestReport = task.CreateTestReport, ...
TestReportFormat = task.TestReportFormat, ...
OutputPath = task.OutputPath, ...
CodeCoveragePlugin = task.CodeCoveragePlugin);
end
obj.executeTests;
end
end
end