Skip to content

Commit 5275334

Browse files
Merge pull request #7 from mathworks/Custom-buildtool-tasks-for-running-examples
Added custom tasks for running examples using ExampleDrivenTester
2 parents 3e72729 + e6daca1 commit 5275334

4 files changed

Lines changed: 131 additions & 4 deletions

File tree

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,35 @@ covPlugin = matlab.unittest.plugins.CodeCoveragePlugin.forFolder("code", "Produc
6767
obj = examplesTester(["examples", "doc"], CodeCoveragePlugin = covPlugin);
6868
obj.executeTests;
6969
```
70+
## Integration with MATLAB's BuildTool
71+
From MATLAB R2025a and onwards, users can use the `ExampleDrivenTesterTask`, a ready-to-use buildtool task shipped with ExamplesDrivenTester for automated example testing.
72+
73+
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.
74+
75+
### Usage Examples
76+
Add the **ExamplesDrivenTester** task to your buildfile.m using the following patterns:
77+
78+
1. Run MATLAB scripts from specified folders and generate a test report (default behavior):
79+
```matlab
80+
plan("runExample") = ExampleDrivenTesterTask(["examples", "doc"]);
81+
```
82+
83+
2. Run MATLAB scripts but do NOT generate a test report:
84+
```matlab
85+
plan("runExample") = ExampleDrivenTesterTask(["examples", "doc"], CreateTestReport = false);
86+
```
87+
88+
3. Run MATLAB scripts and generate a test report in PDF format:
89+
```matlab
90+
plan("runExample") = ExampleDrivenTesterTask(["examples", "doc"], TestReportFormat = "pdf");
91+
```
92+
4. Run MATLAB scripts and generate a code coverage report for code placed in the code folder:
93+
```matlab
94+
95+
reportFormat = matlab.unittest.plugins.codecoverage.CoverageReport('coverage-report');
96+
covPlugin = matlab.unittest.plugins.CodeCoveragePlugin.forFolder("code", "Producing", reportFormat);
97+
plan("runExample") = ExampleDrivenTesterTask(["examples", "doc"], CodeCoveragePlugin = covPlugin);
98+
```
7099

71100
## License
72101

buildfile.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
function plan = buildfile
22
import matlab.buildtool.tasks.CodeIssuesTask
33
import matlab.buildtool.tasks.TestTask
4+
import matlab.buildtool.tasks.CleanTask
45

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

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

12+
plan("clean") = CleanTask;
13+
1114
plan("test") = TestTask('./tests');
1215

16+
% Run MATLAB scripts from specified folder and generate a code coverage report
17+
reportFormat = matlab.unittest.plugins.codecoverage.CoverageReport('coverage-report');
18+
covPlugin = matlab.unittest.plugins.CodeCoveragePlugin.forFolder("toolbox/sampleToolbox/code", "Producing", reportFormat);
19+
plan("runExample") = ExampleDrivenTesterTask("toolbox/sampleToolbox/examples", CodeCoveragePlugin = covPlugin);
20+
1321
plan.DefaultTasks = "test";
1422

1523
end

resources/project/Project.xml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -325,14 +325,23 @@
325325
<Info Name="ExamplesDrivenTester"/>
326326
</Info>
327327
<ProjectPath Location="Root">
328-
<Reference Location="cc363181-1648-4421-ac4e-2d6d7648de9e">
329-
<Info Ref="toolbox" Type="Relative"/>
328+
<Reference Location="3662407c-76fc-4fb3-8e7e-6fce62c1d9b5">
329+
<Info Ref="toolbox/sampleToolbox" Type="Relative"/>
330+
</Reference>
331+
<Reference Location="86dfaf43-70b9-417d-9678-50d5e3603b4d">
332+
<Info Ref="" Type="Relative"/>
330333
</Reference>
331334
<Reference Location="91083c4d-aa37-472b-8349-2152971d6b33">
332335
<Info Ref="toolbox/internal" Type="Relative"/>
333336
</Reference>
334-
<Reference Location="63162818-a3e7-4c1d-beed-3f8397983d80">
335-
<Info Ref="" Type="Relative"/>
337+
<Reference Location="c5fd201e-1476-499f-88cc-f6a34a4b40cd">
338+
<Info Ref="toolbox/sampleToolbox/examples" Type="Relative"/>
339+
</Reference>
340+
<Reference Location="cc363181-1648-4421-ac4e-2d6d7648de9e">
341+
<Info Ref="toolbox" Type="Relative"/>
342+
</Reference>
343+
<Reference Location="df5c02f8-c778-4ad0-aa2f-7169b0afefeb">
344+
<Info Ref="toolbox/sampleToolbox/code" Type="Relative"/>
336345
</Reference>
337346
</ProjectPath>
338347
<Files Location="MLTestManagerCoverageSettings">
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
classdef ExampleDrivenTesterTask < matlab.buildtool.Task
2+
% Buildtool task to run example scripts with optional test & coverage reports.
3+
% Inputs:
4+
% - Folders: string array of M-script locations
5+
% Optional Inputs:
6+
% - CreateTestReport (logical)
7+
% - TestReportFormat (string)
8+
% - ReportOutputFolder (string)
9+
% - CodeCoveragePlugin (object)
10+
11+
properties
12+
Folders (1,:) string
13+
CreateTestReport (1,1) logical
14+
TestReportFormat (1,1) string
15+
OutputPath (1,1) string
16+
CodeCoveragePlugin
17+
end
18+
19+
methods
20+
function task = ExampleDrivenTesterTask(folders, options)
21+
% Constructor
22+
arguments
23+
folders (1,:) string
24+
options.CreateTestReport (1,1) logical = true
25+
options.TestReportFormat (1,1) string {mustBeMember(options.TestReportFormat,["html", "pdf", "docx", "xml"])} = "html"
26+
options.OutputPath(1,1) string = "reports_" + char(datetime('now', 'Format', 'yyyyMMdd_HHmmss'))
27+
options.CodeCoveragePlugin = []
28+
end
29+
30+
task.Description = "Run published examples";
31+
task.Inputs = folders;
32+
33+
% Basic validation
34+
% mustBeMember(options.TestReportFormat, ["html", "pdf", "docx", "xml"]);
35+
for f = folders
36+
if ~isfolder(f)
37+
error("ExampleDrivenTesterTask:FolderNotFound", ...
38+
"Folder not found: %s", f);
39+
end
40+
end
41+
42+
task.Folders = folders;
43+
task.CreateTestReport = options.CreateTestReport;
44+
task.TestReportFormat = options.TestReportFormat;
45+
task.OutputPath= options.OutputPath;
46+
task.CodeCoveragePlugin= options.CodeCoveragePlugin;
47+
48+
if task.CreateTestReport
49+
task.Outputs = task.OutputPath;
50+
else
51+
task.Outputs = string.empty;
52+
end
53+
end
54+
end
55+
56+
methods (TaskAction, Sealed, Hidden)
57+
58+
function runExampleTests(task, ~)
59+
if task.CreateTestReport && ~isfolder(task.OutputPath)
60+
mkdir(task.OutputPath);
61+
end
62+
63+
if isempty(task.CodeCoveragePlugin)
64+
examplesRunner = examplesTester( ...
65+
task.Folders, ...
66+
CreateTestReport = task.CreateTestReport, ...
67+
TestReportFormat = task.TestReportFormat, ...
68+
OutputPath = task.OutputPath);
69+
else
70+
% Pass CodeCoveragePlugin through when provided
71+
examplesRunner = examplesTester( ...
72+
task.Folders, ...
73+
CreateTestReport = task.CreateTestReport, ...
74+
TestReportFormat = task.TestReportFormat, ...
75+
OutputPath = task.OutputPath, ...
76+
CodeCoveragePlugin = task.CodeCoveragePlugin);
77+
end
78+
examplesRunner.executeTests;
79+
end
80+
end
81+
end

0 commit comments

Comments
 (0)