Create Basic Parameterized Test - MATLAB & Simulink (original) (raw)
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 filesierpinski.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 theTestParameter
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
testRemainPixels
method tests the output of thesierpinski
function by verifying that the number of nonzero pixels is the same as expected for a particular level. This method uses thelevel
property and, therefore, results in three test elements—one for each value inlevel
. - The
testClass
method tests the class of the output from thesierpinski
function with each combination of thetype
andlevel
parameter values (that is, exhaustive parameter combination). The method results in nine test elements. - The
testDefaultL1Output
method does not use aTestParameter
property 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, thetestNumel
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.
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 ofTestSuite
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.
Running TestCarpet ..... Done TestCarpet
Alternatively, you can create the same test suite directly using thefromFile
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