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
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, 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