Create Advanced Parameterized Test
This example shows how to create a test that is parameterized in theTestClassSetup
,TestMethodSetup
, andTest
methods
blocks. The example test class tests random number generation.
Create TestRand Test Class
In a file in your current folder, create theTestRand
类测试随机数创的各个方面eration. Define the properties used for parameterized testing.
classdefTestRand < matlab.unittest.TestCaseproperties(ClassSetupParameter) generator = {'twister','combRecursive','multFibonacci'};endproperties(MethodSetupParameter) seed = {0,123,4294967295};endproperties(TestParameter) dim1 = struct('small',1,'medium',2,'large',3); dim2 = struct('small',2,'medium',3,'large',4); dim3 = struct('small',3,'medium',4,'large',5); type = {'single','double'};endend
In theTestRand
class, eachproperties
block corresponds to parameterization at a particular level. The class setup-level parameterization defines the type of random number generator. The method setup-level parameterization defines the seed for the random number generator, and the test-level parameterization defines the data type and size of the random values.
Define Test Class and Test Method Setup Methods
Define the setup methods at the test class and test method levels. These methods register the initial random number generator state. After the framework runs the tests, the methods restore the original state. TheclassSetup
method defines the type of random number generator, and themethodSetup
method seeds the generator.
classdefTestRand < matlab.unittest.TestCaseproperties(ClassSetupParameter) generator = {'twister','combRecursive','multFibonacci'};endproperties(MethodSetupParameter) seed = {0,123,4294967295};endproperties(TestParameter) dim1 = struct('small',1,'medium',2,'large',3); dim2 = struct('small',2,'medium',3,'large',4); dim3 = struct('small',3,'medium',4,'large',5); type = {'single','double'};endmethods(TestClassSetup)functionclassSetup(testCase,generator) orig = rng; testCase.addTeardown(@rng,orig) rng(0,generator)endendmethods(TestMethodSetup)functionmethodSetup(testCase,seed) orig = rng; testCase.addTeardown(@rng,orig) rng(seed)endendend
Define Test Method with Sequential Parameter Combination
Define thetestSize
method in amethods
block with theTest
andParameterCombination = 'sequential'
attributes.
classdefTestRand < matlab.unittest.TestCaseproperties(ClassSetupParameter) generator = {'twister','combRecursive','multFibonacci'};endproperties(MethodSetupParameter) seed = {0,123,4294967295};endproperties(TestParameter) dim1 = struct('small',1,'medium',2,'large',3); dim2 = struct('small',2,'medium',3,'large',4); dim3 = struct('small',3,'medium',4,'large',5); type = {'single','double'};endmethods(TestClassSetup)functionclassSetup(testCase,generator) orig = rng; testCase.addTeardown(@rng,orig) rng(0,generator)endendmethods(TestMethodSetup)functionmethodSetup(testCase,seed) orig = rng; testCase.addTeardown(@rng,orig) rng(seed)endendmethods(Test, ParameterCombination ='sequential')functiontestSize(testCase,dim1,dim2,dim3) testCase.verifySize(rand(dim1,dim2,dim3),[dim1 dim2 dim3])endendend
The method tests the size of the output for each corresponding parameter value indim1
,dim2
, anddim3
. For a givenTestClassSetup
andTestMethodSetup
parameterization, the framework calls thetestSize
method three times — one time for each of the'small'
,'medium'
, and'large'
values. For example, to test with all of the'medium'
values, the framework usestestCase.verifySize(rand(2,3,4),[2 3 4])
.
Define Test Method with Pairwise Parameter Combination
Define thetestRepeatable
method in amethods
block with theTest
andParameterCombination = '成对'
attributes.
classdefTestRand < matlab.unittest.TestCaseproperties(ClassSetupParameter) generator = {'twister','combRecursive','multFibonacci'};endproperties(MethodSetupParameter) seed = {0,123,4294967295};endproperties(TestParameter) dim1 = struct('small',1,'medium',2,'large',3); dim2 = struct('small',2,'medium',3,'large',4); dim3 = struct('small',3,'medium',4,'large',5); type = {'single','double'};endmethods(TestClassSetup)functionclassSetup(testCase,generator) orig = rng; testCase.addTeardown(@rng,orig) rng(0,generator)endendmethods(TestMethodSetup)functionmethodSetup(testCase,seed) orig = rng; testCase.addTeardown(@rng,orig) rng(seed)endendmethods(Test, ParameterCombination ='sequential')functiontestSize(testCase,dim1,dim2,dim3) testCase.verifySize(rand(dim1,dim2,dim3),[dim1 dim2 dim3])endendmethods(Test, ParameterCombination =“成对”)functiontestRepeatable(testCase,dim1,dim2,dim3) state = rng; firstRun = rand(dim1,dim2,dim3); rng(state) secondRun = rand(dim1,dim2,dim3); testCase.verifyEqual(firstRun,secondRun)endendend
The method verifies that the random number generator results are repeatable. For a givenTestClassSetup
andTestMethodSetup
parameterization, the framework calls thetestRepeatable
method 10 times to ensure testing with each pair of parameter values specified bydim1
,dim2
, anddim3
. If the parameter combination were exhaustive, the framework would call the method 3³ = 27 times.
Define Test Method with Exhaustive Parameter Combination
Define thetestClass
method in amethods
block with theTest
attribute. Because theParameterCombination
attribute is not specified, the parameter combination is exhaustive by default.
classdefTestRand < matlab.unittest.TestCaseproperties(ClassSetupParameter) generator = {'twister','combRecursive','multFibonacci'};endproperties(MethodSetupParameter) seed = {0,123,4294967295};endproperties(TestParameter) dim1 = struct('small',1,'medium',2,'large',3); dim2 = struct('small',2,'medium',3,'large',4); dim3 = struct('small',3,'medium',4,'large',5); type = {'single','double'};endmethods(TestClassSetup)functionclassSetup(testCase,generator) orig = rng; testCase.addTeardown(@rng,orig) rng(0,generator)endendmethods(TestMethodSetup)functionmethodSetup(testCase,seed) orig = rng; testCase.addTeardown(@rng,orig) rng(seed)endendmethods(Test, ParameterCombination ='sequential')functiontestSize(testCase,dim1,dim2,dim3) testCase.verifySize(rand(dim1,dim2,dim3),[dim1 dim2 dim3])endendmethods(Test, ParameterCombination =“成对”)functiontestRepeatable(testCase,dim1,dim2,dim3) state = rng; firstRun = rand(dim1,dim2,dim3); rng(state) secondRun = rand(dim1,dim2,dim3); testCase.verifyEqual(firstRun,secondRun)endendmethods(Test)functiontestClass(testCase,dim1,dim2,type) testCase.verifyClass(rand(dim1,dim2,type),type)endendend
The method verifies that the class of the output fromrand
is the same as the expected class. For a givenTestClassSetup
andTestMethodSetup
parameterization, the framework calls thetestClass
method 3×3×2 = 18 times to ensure testing with each combination ofdim1
,dim2
, andtype
parameter values.
Create Suite from Test Class
At the command prompt, create a suite from theTestRand
class.
suite = matlab.unittest.TestSuite.fromClass(?TestRand)
suite = 1×279 Test array with properties: Name ProcedureName TestClass BaseFolder Parameterization SharedTestFixtures Tags Tests Include: 17 Unique Parameterizations, 0 Shared Test Fixture Classes, 0 Tags.
For a givenTestClassSetup
andTestMethodSetup
parameterization, the framework creates 3+10+18 = 31 test elements. These 31 elements are called for eachTestMethodSetup
parameterization (resulting in 3×31 = 93 test elements for eachTestClassSetup
parameterization). There are threeTestClassSetup
parameterizations; therefore, the suite has a total of 3×93 = 279 test elements.
Query the name of the first test element.
suite(1).Name
ans = 'TestRand[generator=twister]/[seed=value1]testClass(dim1=small,dim2=small,type=single)'
The name of the first element is composed of these parts:
Test class:
TestRand
Class setup property and parameter name:
[generator=twister]
Method setup property and parameter name:
[seed=value1]
Test method name:
testClass
Test method property and parameter names:
(dim1=small,dim2=small,type=single)
The parameter name for theseed
property is not particularly meaningful (value1
). The testing framework provided this name because theseed
property is specified as a cell array. For a more meaningful name, define theseed
property as a structure with descriptive field names.
Run Suite Created Using Selector
At the command prompt, create a selector to select test elements that test the'twister'
generator for'single'
precision. Create a suite by omitting test elements that use properties with the'large'
parameter name.
importmatlab.unittest.selectors.HasParameters = HasParameter('Property','generator','Name','twister') &...HasParameter('Property','type','Name','single') &...~HasParameter('Name','large'); suite2 = matlab.unittest.TestSuite.fromClass(?TestRand,s)
suite2 = 1×12 Test array with properties: Name ProcedureName TestClass BaseFolder Parameterization SharedTestFixtures Tags Tests Include: 9 Unique Parameterizations, 0 Shared Test Fixture Classes, 0 Tags.
If you first generate the full suite from theTestRand
class, you can construct the same filtered suite using theselectIf
method.
suite = matlab.unittest.TestSuite.fromClass(?TestRand); suite2 = selectIf(suite,s);
Run the filtered test suite.
suite2.run;
Running TestRand .......... .. Done TestRand __________
Run Suite from Method Using Selector
Create a selector that omits test elements that use properties with the'large'
or'medium'
parameter names. Limit results to test elements from thetestRepeatable
method.
importmatlab.unittest.selectors.HasParameters = ~(HasParameter('Name','large') | HasParameter('Name','medium')); suite3 = matlab.unittest.TestSuite.fromMethod(?TestRand,'testRepeatable',s); {suite3.Name}'
ans = 9×1 cell array {'TestRand[generator=twister]/[seed=value1]testRepeatable(dim1=small,dim2=small,dim3=small)' } {'TestRand[generator=twister]/[seed=value2]testRepeatable(dim1=small,dim2=small,dim3=small)' } {'TestRand[generator=twister]/[seed=value3]testRepeatable(dim1=small,dim2=small,dim3=small)' } {'TestRand[generator=combRecursive]/[seed=value1]testRepeatable(dim1=small,dim2=small,dim3=small)'} {'TestRand[generator=combRecursive]/[seed=value2]testRepeatable(dim1=small,dim2=small,dim3=small)'} {'TestRand[generator=combRecursive]/[seed=value3]testRepeatable(dim1=small,dim2=small,dim3=small)'} {'TestRand[generator=multFibonacci]/[seed=value1]testRepeatable(dim1=small,dim2=small,dim3=small)'} {'TestRand[generator=multFibonacci]/[seed=value2]testRepeatable(dim1=small,dim2=small,dim3=small)'} {'TestRand[generator=multFibonacci]/[seed=value3]testRepeatable(dim1=small,dim2=small,dim3=small)'}
Run the test suite.
suite3.run;
Running TestRand ......... Done TestRand __________
Run All Double Precision Tests
At the command prompt, run all of the test elements from theTestRand
class that use the'double'
parameter name.
runtests('TestRand','ParameterName','double');
Running TestRand .......... .......... .......... .......... .......... .......... .......... .......... . Done TestRand __________
See Also
matlab.unittest.TestSuite
|matlab.unittest.TestCase
|matlab.unittest.selectors.HasParameter