function [passed,results] = run_scdds_core_tests(test_case, coverage_report) if nargin==0 || isempty(test_case) test_case = 'basic'; % default end if nargin < 2 || isempty(coverage_report) coverage_report = false; % default end if coverage_report assert(~verLessThan('matlab','9.6.0'),'coverage_report=true needs MATLAB 9.6.0 or later'); assert( strcmpi(test_case,'coverage'),'coverage_report=true should only be used with test_case=''coverage'''); end needXML=~isempty(getenv('GITLAB_CI')) && ~verLessThan('matlab','8.6.0'); needCOV=~isempty(getenv('GITLAB_CI')) && ~verLessThan('matlab','9.6.0') || coverage_report; %% Default outputs passed=false; results=[]; %% Import some classes we need import matlab.unittest.selectors.HasTag; import matlab.unittest.constraints.ContainsSubstring; import matlab.unittest.selectors.HasName; import matlab.unittest.TestRunner import matlab.unittest.plugins.codecoverage.CoberturaFormat; import matlab.unittest.plugins.CodeCoveragePlugin; %% Paths % add path of toolbox to make sure it is in the path tbxpath = fileparts(mfilename('fullpath')); projectpath = getenv('CI_PROJECT_DIR'); if isempty(projectpath), projectpath = tbxpath; end scdds_core_paths; addpath(fullfile(tbxpath,'tests')); %% Name tbxname = getenv('TBXTARGET'); if isempty(tbxname) % Fallback value: name of folder [~,tbxname] = fileparts(tbxpath); end %% Generate test suite testspath = fullfile(tbxpath,'tests'); lastwarn('',''); % clear last warning suite_all = matlab.unittest.TestSuite.fromFolder(testspath); [~,s] = lastwarn(); if isequal(s,'MATLAB:unittest:TestSuite:FileExcluded') fprintf('File excluded during test suite creation - possible syntax errors in a test class\n'); return end % Identify tests without any tags mask = cellfun(@isempty,{suite_all.Tags}); if any(mask) fprintf('Some tests do not have TestTags set and are unreachable from run_meq_tests:\n'); fprintf('\t%s\n',suite_all(mask).Name); return end useparallel = false; % switch for parallel testing using parallel toolbox paravail = ~isempty(ver('distcomp')); % check if parallel toolbox is installed fprintf('running %s\n',mfilename('fullpath')) switch lower(test_case) case {'unit'} s = HasTag('unit'); case {'algos'} % add algos folder tests suite_algos = testsuite('algos','IncludingSubfolders',true,'superclass','SCDDSalgo_test'); suite_all = [suite_all,suite_algos]; s = HasTag('algos'); otherwise % assume tag with this name s = HasTag(test_case); end suite = suite_all.selectIf(s); if isempty(suite) fprintf('\nEmpty test suite returned for TestTag=''%s''\n',test_case); return; end %% run it fprintf('Main Test File: %s\nStart test case: %s\n%s\n\n',mfilename('fullpath'),test_case,datestr(now)); runner = matlab.unittest.TestRunner.withTextOutput; if needXML || needCOV prefix = sprintf('test_%s',tbxname); suffix = version('-release'); dirOut = dir(fullfile(tbxpath, '**', '*.m')); codeFilePaths = string({dirOut.folder}) + filesep + string({dirOut.name}); % remove files to exclude filePathsToExclude = fullfile(tbxpath,'mds','mds-matlab-structs'); codeFilePaths(contains(codeFilePaths, filePathsToExclude)) = []; end if needXML % Add some JUnit XML file with tests results xmlFile = fullfile(projectpath,sprintf('%s_%s_%s.xml',prefix,test_case,suffix)); p = CodeCoveragePlugin.forFile(codeFilePaths,... 'Producing',CoberturaFormat(xmlFile)); runner.addPlugin(p) end if needCOV % Add some code coverage report switch lower(test_case) case 'coverage' % Produce HTML report reportFolder = fullfile(projectpath,sprintf('%s_%s_cov',prefix,suffix)); reportFormat = matlab.unittest.plugins.codecoverage.CoverageReport(reportFolder); otherwise % Produce XML file in Cobertura format (for Gitlab MR viz.) xmlFile = fullfile(projectpath,sprintf('%s_%s_%s_cov.xml',prefix,test_case,suffix)); reportFormat = matlab.unittest.plugins.codecoverage.CoberturaFormat(xmlFile); end p = matlab.unittest.plugins.CodeCoveragePlugin.forFile(codeFilePaths,... 'Producing',reportFormat); runner.addPlugin(p) end if useparallel && paravail results = runInParallel(runner,suite); else results = run(runner,suite); end fprintf('\nTotal test duration: %5.2fs\n',sum(table(results).Duration)) %% % close any parallel pools if paravail, delete(gcp('nocreate')); end %% Display results fprintf('Passed tests: \n'); disp(table(results([results.Passed]))); if all([results.Passed]) fprintf('\nPassed all tests\n') passed = true; elseif any([results.Failed]) fprintf('\nSome tests Failed\n') disp(table(results([results.Failed]))) passed = false; elseif any([results.Incomplete]) fprintf('\nSome tests Incomplete\n') disp(table(results([results.Incomplete]))); passed = true; % pass tests even if some were skipped else % the conditions above should cover all cases, otherwise error('something is very wrong - please check') end end