-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathnwbtest.m
136 lines (115 loc) · 4.93 KB
/
nwbtest.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
function results = nwbtest(varargin)
% NWBTEST Run MatNWB test suite.
%
% The nwbtest function provides a simple way to run the MatNWB test
% suite. It writes a JUnit-style XML file containing the test results
% (testResults.xml) and a Cobertura-style XML file containing a code
% coverage report (coverage.xml).
%
% EXITCODE = nwbtest() runs all tests in the MatNWB test suite and
% returns a logical 1 (true) if any tests failed, or a logical 0 (false)
% if all tests passed.
%
% EXITCODE = nwbtest('Verbosity', VERBOSITY) runs the tests at the
% specified VERBOSITY level. VERBOSITY can be specified as either a
% numeric value (1, 2, 3, or 4) or a value from the
% matlab.unittest.Verbosity enumeration.
%
% EXITCODE = nwbtest(NAME, VALUE, ...) also supports those name-value
% pairs of the matlab.unittest.TestSuite.fromPackage function.
%
% Examples:
%
% % Run all tests in the MatNWB test suite.
% nwbtest()
%
% % Run all unit tests in the MatNWB test suite.
% nwbtest('Name', 'tests.unit.*')
%
% % Run only tests that match the ProcedureName 'testSmoke*'.
% nwbtest('ProcedureName', 'testSmoke*')
%
% See also: matlab.unittest.TestSuite.fromPackage
import matlab.unittest.TestSuite;
import matlab.unittest.TestRunner;
import matlab.unittest.plugins.XMLPlugin;
import matlab.unittest.plugins.CodeCoveragePlugin;
import matlab.unittest.plugins.codecoverage.CoberturaFormat;
try
parser = inputParser;
parser.KeepUnmatched = true;
parser.addParameter('Verbosity', 1);
parser.addParameter('Selector', [])
parser.addParameter('Namespace', 'tests')
parser.addParameter('ProduceCodeCoverage', true)
parser.addParameter('ReportOutputFolder', '')
parser.parse(varargin{:});
if isempty(parser.Results.ReportOutputFolder)
numReports = 1 + parser.Results.ProduceCodeCoverage;
[reportOutputFolder, folderCleanupObject] = createReportsFolder(numReports); %#ok<ASGLU>
else
reportOutputFolder = parser.Results.ReportOutputFolder;
end
% Create test suite
pvcell = struct2pvcell(parser.Unmatched);
suite = TestSuite.fromPackage(parser.Results.Namespace, ...
'IncludingSubpackages', true, pvcell{:});
if ~isempty(parser.Results.Selector)
suite = suite.selectIf(parser.Results.Selector);
end
suite = suite.sortByFixtures();
% Configure test runner
runner = TestRunner.withTextOutput('Verbosity', parser.Results.Verbosity);
resultsFile = fullfile(reportOutputFolder, 'testResults.xml');
runner.addPlugin(XMLPlugin.producingJUnitFormat(resultsFile));
if parser.Results.ProduceCodeCoverage
filesForCoverage = getFilesForCoverage();
if ~verLessThan('matlab', '9.3') && ~isempty(filesForCoverage)
coverageResultFile = fullfile(reportOutputFolder, 'coverage.xml');
runner.addPlugin(CodeCoveragePlugin.forFile(filesForCoverage,...
'Producing', CoberturaFormat(coverageResultFile)));
end
end % add cobertura coverage
% Run tests
results = runner.run(suite);
if ~nargout
display(results)
end
catch e
disp(e.getReport('extended'));
results = [];
end
end
function pv = struct2pvcell(s)
p = fieldnames(s);
v = struct2cell(s);
n = 2*numel(p);
pv = cell(1,n);
pv(1:2:n) = p;
pv(2:2:n) = v;
end
function filePaths = getFilesForCoverage()
matnwbDir = misc.getMatnwbDir();
coverageIgnoreFile = fullfile(matnwbDir, '+tests', '.coverageignore');
ignorePatterns = string(splitlines( fileread(coverageIgnoreFile) ));
ignorePatterns(ignorePatterns=="") = [];
mFileListing = dir(fullfile(matnwbDir, '**', '*.m'));
absoluteFilePaths = fullfile({mFileListing.folder}, {mFileListing.name});
relativePaths = replace(absoluteFilePaths, [matnwbDir filesep], '');
keep = ~startsWith(relativePaths, ignorePatterns);
filePaths = fullfile(matnwbDir, relativePaths(keep));
end
function [reportOutputFolder, folderCleanupObject] = createReportsFolder(numReports)
reportRootFolder = fullfile(misc.getMatnwbDir, 'docs', 'reports');
timestamp = string(datetime("now", 'Format', 'uuuu_MM_dd_HHmm'));
reportOutputFolder = fullfile(reportRootFolder, timestamp);
if ~isfolder(reportOutputFolder); mkdir(reportOutputFolder); end
folderCleanupObject = onCleanup(...
@() deleteFolderIfCanceled(reportOutputFolder, numReports));
function deleteFolderIfCanceled(folderPath, numReports)
L = dir(fullfile(folderPath, '*.xml'));
if ~isequal(numel(L), numReports)
rmdir(folderPath, 's')
end
end
end