5

I'm trying to create a parametrized Matlab unittest where the TestParameter properties are generated "dynamically" by some code (e.g., with a for loop).

As a simplified example, suppose my code is

classdef partest < matlab.unittest.TestCase
    properties (TestParameter)
        level = struct('level1', 1, 'level2', 2, 'level3', 3, 'level4', 4)
    end

    methods (Test)
        function testModeling(testCase, level)
            fprintf('Testing level %d\n', level);
        end
    end
end

but in my real code, I have 100 levels. I tried to put this in a separate method, like

classdef partest < matlab.unittest.TestCase
    methods (Static)
        function level = getLevel()
            for i=1:100
               level.(sprintf('Level%d', i)) = i;
            end
        end
    end

    properties (TestParameter)
        level = partest.getLevel()
    end

    methods (Test)
        function testModeling(testCase, level)
            fprintf('Testing level %d\n', level);
        end
    end
end

but that does not work; I get the error (Matlab 2014b):

>> runtests partest
Error using matlab.unittest.TestSuite.fromFile (line 163)
The class partest has no property or method named 'getLevel'.

I could move the getLevel() function to another file, but I'd like to keep it in one file.

Amro
  • 123,847
  • 25
  • 243
  • 454
Frank Meulenaar
  • 1,207
  • 3
  • 13
  • 23
  • 1
    I can not run your code because my matlab version is to old, but you could try `level = cell2struct(num2cell(1:n), arrayfun(@(x)(['level',num2str(x)]),1:n,'uni',false), 2)` in your original class. – Daniel Feb 09 '16 at 16:00
  • @Daniel: of course my real example is more complicated :) – Frank Meulenaar Feb 10 '16 at 06:22

1 Answers1

4

Same here (R2015b), it looks like a TestParameter property cannot be initialized with a static function call...

Fortunately the solution is quite simple, use a local function instead:

partest.m

classdef partest < matlab.unittest.TestCase
    properties (TestParameter)
        level = getLevel()
    end

    methods (Test)
        function testModeling(testCase, level)
            fprintf('Testing level %d\n', level);
        end
    end
end

function level = getLevel()
    for i=1:100
       level.(sprintf('Level%d', i)) = i;
    end
end

(Note that all the above code is contained in one file partest.m).

Now this should work:

>> run(matlab.unittest.TestSuite.fromFile('partest.m'))

Note:

Being a local function, it won't be visible outside the class. If you also need to expose it, just add a static function acting as a simple wrapper:

classdef partest < matlab.unittest.TestCase
    ...

    methods (Static)
        function level = GetLevelFunc()
            level = getLevel();
        end
    end
end

function level = getLevel()
    ...
end
Amro
  • 123,847
  • 25
  • 243
  • 454