Skip to content
Snippets Groups Projects
run_scdds_core_tests.m 4.87 KiB
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