Documentation Center

  • Trial Software
  • Product Updates

Create Basic Parameterized Test

This example shows how to create a basic parameterized test.

Create Function to Test

In a file in your working folder, create a function in the file sierpinski.m. This function returns a matrix representing an image of a Sierpinski carpet fractal. It takes as input the fractal level and an optional data type.

function carpet = sierpinski(nLevels,classname)
if nargin == 1
    classname = 'single';
end

mSize = 3^nLevels;
carpet = ones(mSize,classname);

cutCarpet(1,1,mSize,nLevels); % begin recursion

    function cutCarpet(x,y,s,cL)
        if cL
            ss = s/3; % define subsize
            for lx = 0:2
                for ly = 0:2
                    if lx == 1 && ly == 1  
                        % remove center square
                        carpet(x+ss:x+2*ss-1,y+ss:y+2*ss-1) = 0;
                    else
                        % recurse
                        cutCarpet(x + lx*ss, y + ly*ss, ss, cL-1);
                    end
                end
            end
        end
    end
end

Create TestCarpet Test Class

In a file in your working folder, create a new class, TestCarpet, to test the sierpinski function.

classdef TestCarpet < matlab.unittest.TestCase

Define properties Block

Define the properties used for parameterized testing. In the TestCarpet class, define these properties in a property block with the TestParameter attribute.

    properties (TestParameter)
        type = {'single','double','uint16'};
        level = struct('small', 2,'medium', 4, 'large', 6);
        side = struct('small', 9, 'medium', 81,'large', 729);
    end

The type property contains the different data types you want to test. The level property contains the different fractal level you want to test. The side property contains the number of rows and columns in the Sierpinski carpet matrix and corresponds to the level property. To provide meaningful names for each parameterization value, level and side are defined as structs.

Define Test methods Block

Define the following test methods in the TestCarpet class.

    methods (Test)
        function testRemainPixels(testCase, level)
            % expected number pixels equal to 1
            expPixelCount = 8^level;
            % actual number pixels equal to 1
            actPixels = find(sierpinski(level));
            testCase.verifyNumElements(actPixels,expPixelCount);
        end
        
        function testClass(testCase, type, level)
            testCase.verifyClass(...
                sierpinski(level,type), type);
        end
        
        function testDefaultL1Output(testCase)
            exp = single([1 1 1; 1 0 1; 1 1 1]);
            testCase.verifyEqual(sierpinski(1), exp);
        end
        
    end

The testRemainPixes method tests the output of the sierpinski function by verifying that the number of nonzero pixels is the same as expected for a particular level. This method uses the level property and, therefore, results in three test elements—one for each value in level. The testClass method tests the class of the output from the sierpinski function with each combination of the type and level properties. This approach results in nine test elements. The testDefaultL1Output test method does not use a TestParameter property and, therefore, is not parameterized. This test method verifies that the level 1 matrix contains the expected values. Since the test method is not parameterized, it results in a one test element.

In the test methods above, you did not define the ParameterCombination attribute of the Test methods block. This attribute is, by default, 'exhaustive'. The test framework invokes a given test method once for every combination of the test parameters.

Define Test methods Block with ParameterCombination Attribute

Define the following test methods in the TestCarpet class to ensure that the matrix output by the sierpinski function has the correct number of elements. Set the ParameterCombination attribute to 'sequential'.

    methods (Test, ParameterCombination='sequential')
        function testNumel(testCase, level, side)
            import matlab.unittest.constraints.HasElementCount;
            testCase.verifyThat(sierpinski(level),...
                HasElementCount(side^2));
        end
    end
end

Test methods with the ParameterCombination attribute set to 'sequential' are invoked once for each corresponding value of the parameter. The properties, level and side, must have the same number of values. Since these properties each have three values, the testNumel method is invoked three times.

TestCarpet Class Definition Summary

The complete contents of TestCarpet.m follows.

classdef TestCarpet < matlab.unittest.TestCase
    
    properties (TestParameter)
        type = {'single','double','uint16'};
        level = struct('small', 2,'medium', 4, 'large', 6);
        side = struct('small', 9, 'medium', 81,'large', 729);
    end
    
    methods (Test)
        function testRemainPixels(testCase, level)
            % expected number pixels equal to 1
            expPixelCount = 8^level;
            % actual number pixels equal to 1
            actPixels = find(sierpinski(level));
            testCase.verifyNumElements(actPixels,expPixelCount);
        end
        
        function testClass(testCase, type, level)
            testCase.verifyClass(...
                sierpinski(level,type), type);
        end
        
        function testDefaultL1Output(testCase)
            exp = single([1 1 1; 1 0 1; 1 1 1]);
            testCase.verifyEqual(sierpinski(1), exp);
        end
    end
    
    methods (Test, ParameterCombination='sequential')
        function testNumel(testCase, level, side)
            import matlab.unittest.constraints.HasElementCount;
            testCase.verifyThat(sierpinski(level),...
                HasElementCount(side^2));
        end
    end
end

Run All Tests

At the command prompt, create a suite from TestCarpet.m.

suite = matlab.unittest.TestSuite.fromFile('TestCarpet.m');
{suite.Name}'
ans = 

    'TestCarpet/testNumel(level=small,side=small)'
    'TestCarpet/testNumel(level=medium,side=medium)'
    'TestCarpet/testNumel(level=large,side=large)'
    'TestCarpet/testRemainPixels(level=small)'
    'TestCarpet/testRemainPixels(level=medium)'
    'TestCarpet/testRemainPixels(level=large)'
    'TestCarpet/testClass(type=single,level=small)'
    'TestCarpet/testClass(type=single,level=medium)'
    'TestCarpet/testClass(type=single,level=large)'
    'TestCarpet/testClass(type=double,level=small)'
    'TestCarpet/testClass(type=double,level=medium)'
    'TestCarpet/testClass(type=double,level=large)'
    'TestCarpet/testClass(type=uint16,level=small)'
    'TestCarpet/testClass(type=uint16,level=medium)'
    'TestCarpet/testClass(type=uint16,level=large)'
    'TestCarpet/testDefaultL1Output'

The suite had 16 test elements. The element's Name indicates any parameterization.

suite.run;
Running TestCarpet
..........
......
Done TestCarpet
__________

Run Tests with level Parameter Property Named small

Use the selectIf method of the TestSuite to select test elements that use a particular parameterization. Select all test elements that use the parameter name small in the level parameter property list.

s1 = suite.selectIf('ParameterName','small');
{s1.Name}'
ans = 

    'TestCarpet/testNumel(level=small,side=small)'
    'TestCarpet/testRemainPixels(level=small)'
    'TestCarpet/testClass(type=single,level=small)'
    'TestCarpet/testClass(type=double,level=small)'
    'TestCarpet/testClass(type=uint16,level=small)'

The suite has five elements.

s1.run;
Running TestCarpet
.....
Done TestCarpet
__________

Alternatively, create the same test suite directly from the fromFile method of TestSuite.

import matlab.unittest.selectors.HasParameter;
s1 = matlab.unittest.TestSuite.fromFile('TestCarpet.m',...
    HasParameter('Name','small'));

See Also

| |

Related Examples

Was this topic helpful?