Build out MATLAB test framework and core integration coverage

This commit is contained in:
Silas Oettinghaus
2026-03-24 17:23:02 +01:00
parent 9446dfb888
commit a592ebefda
154 changed files with 2281 additions and 1305 deletions

112
Tests/run_all_tests.m Normal file
View File

@@ -0,0 +1,112 @@
function results = run_all_tests(options)
%RUN_ALL_TESTS Run repository tests using named profiles.
% results = run_all_tests() runs the fast profile.
% results = run_all_tests("profile","full") runs all implemented
% non-hardware tests.
%
% Profiles:
% fast fast unit tests only
% full all implemented non-hardware tests
% unit all implemented unit tests
% hardware hardware-tagged tests only
% placeholder placeholder tests only
% all every discovered test
arguments
options.profile (1, 1) string {mustBeMember(options.profile, ...
["fast", "full", "unit", "hardware", "placeholder", "all"])} = "fast"
options.strict (1, 1) logical = false
end
import matlab.unittest.TestSuite
testsRoot = fileparts(mfilename("fullpath"));
repoRoot = fileparts(testsRoot);
originalPath = path();
cleanupObj = onCleanup(@() path(originalPath)); %#ok<NASGU>
addRepositoryPaths(repoRoot, testsRoot);
suite = TestSuite.fromFolder(testsRoot, "IncludingSubfolders", true);
notImplementedCount = countPlaceholderTests(testsRoot);
suite = filterSuiteForProfile(suite, options.profile);
fprintf("Running profile '%s' with %d tests.\n", options.profile, numel(suite));
fprintf("Not implemented tests: %d\n", notImplementedCount);
if isempty(suite)
warning("run_all_tests:EmptySuite", ...
"No tests matched the '%s' profile.", options.profile);
results = matlab.unittest.TestResult.empty();
return
end
results = run(suite);
fprintf("Passed: %d | Failed: %d | Incomplete: %d\n", ...
nnz([results.Passed]), nnz([results.Failed]), ...
nnz([results.Incomplete]));
if options.strict && any([results.Failed])
error("run_all_tests:FailuresDetected", ...
"Test failures detected in profile '%s'.", options.profile);
end
end
function suite = filterSuiteForProfile(suite, profile)
switch profile
case "fast"
suite = includeTags(suite, "fast");
suite = excludeTags(suite, ["placeholder", "hardware", "slow"]);
case "full"
suite = excludeTags(suite, ["placeholder", "hardware"]);
case "unit"
suite = includeTags(suite, "unit");
suite = excludeTags(suite, ["placeholder", "hardware"]);
case "hardware"
suite = includeTags(suite, "hardware");
suite = excludeTags(suite, "placeholder");
case "placeholder"
suite = includeTags(suite, "placeholder");
case "all"
% no filtering
end
end
function suite = includeTags(suite, tags)
tags = string(tags);
mask = arrayfun(@(test) any(ismember(string(test.Tags), tags)), suite);
suite = suite(mask);
end
function suite = excludeTags(suite, tags)
tags = string(tags);
mask = arrayfun(@(test) any(ismember(string(test.Tags), tags)), suite);
suite = suite(~mask);
end
function addRepositoryPaths(repoRoot, testsRoot)
addpath(repoRoot);
addpath(testsRoot);
folders = ["Classes", "Functions", "Datatypes", "Libs"];
for folder = folders
fullFolder = fullfile(repoRoot, folder);
if isfolder(fullFolder)
addpath(genpath(fullFolder));
end
end
end
function count = countPlaceholderTests(testsRoot)
placeholderFiles = dir(fullfile(testsRoot, '**', '*_test.m'));
count = 0;
for idx = 1:numel(placeholderFiles)
filePath = fullfile(placeholderFiles(idx).folder, placeholderFiles(idx).name);
source = fileread(filePath);
if contains(source, 'assumeFail(')
count = count + 1;
end
end
end