Create Basic Parameterized Test
This example shows how to create a parameterized test to test the output of a function in terms of value, class, and size.
Create Function to Test
In your current 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(levels,classname) if nargin == 1 classname = 'single'; end msize = 3^levels; carpet = ones(msize,classname); cutCarpet(1,1,msize,levels) % 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 current folder, create the TestCarpet
class to test the sierpinski function. Define the properties
used for parameterized testing in a properties block with the
TestParameter attribute.
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 end
The type property contains the different data types you
want to test. The level property contains the different
fractal levels 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.
Define Test methods Block
In a methods block with the Test
attribute, define three test methods:
The
testRemainPixelsmethod tests the output of thesierpinskifunction by verifying that the number of nonzero pixels is the same as expected for a particular level. This method uses thelevelproperty and, therefore, results in three test elements—one for each value inlevel.The
testClassmethod tests the class of the output from thesierpinskifunction with each combination of thetypeandlevelparameter values (that is, exhaustive parameter combination). The method results in nine test elements.The
testDefaultL1Outputmethod does not use aTestParameterproperty and, therefore, is not parameterized. The method verifies that the level 1 matrix contains the expected values. Because the test method is not parameterized, it results in one test element.
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) expPixelCount = 8^level; 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 end
Define Test methods Block with ParameterCombination Attribute
Define the testNumel method to ensure that the matrix
returned by the sierpinski function has the correct number of
elements. Set the ParameterCombination attribute for the
method to 'sequential'. Because the level
and side properties each specify three parameter values, the
testNumel method is invoked three times — one time
for each of the 'small', 'medium', and
'large' values.
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) expPixelCount = 8^level; 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.
The suite has 16 test elements. MATLAB® includes parameterization information in the names of the suite
elements.
suite = matlab.unittest.TestSuite.fromFile('TestCarpet.m');
{suite.Name}'
ans =
16×1 cell array
{'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' }
Run the tests.
suite.run
Running TestCarpet
.......... ......
Done TestCarpet
__________
ans =
1×16 TestResult array with properties:
Name
Passed
Failed
Incomplete
Duration
Details
Totals:
16 Passed, 0 Failed, 0 Incomplete.
2.459 seconds testing time.
Run Tests with level Property Named 'small'
Use the selectIf method of
TestSuite to select test elements that use a particular
parameterization. Select all test elements that use the parameter name
'small' in the level parameterization
property list. The filtered suite has five elements.
s1 = suite.selectIf('ParameterName','small'); {s1.Name}'
ans =
5×1 cell array
{'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)'}
Run the filtered test suite.
s1.run;
Running TestCarpet ..... Done TestCarpet __________
Alternatively, you can create the same test suite directly using the
fromFile method of TestSuite.
import matlab.unittest.selectors.HasParameter s1 = matlab.unittest.TestSuite.fromFile('TestCarpet.m', ... HasParameter('Name','small'));
See Also
matlab.unittest.TestCase | matlab.unittest.selectors.HasParameter | matlab.unittest.TestSuite