Main Content

Create Advanced Parameterized Test

This example shows how to create a test that is parameterized in theTestClassSetup,TestMethodSetup, andTestmethodsblocks. 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 theTestRandclass, eachpropertiesblock 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. TheclassSetupmethod defines the type of random number generator, and themethodSetupmethod 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 thetestSizemethod in amethodsblock with theTestandParameterCombination = '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 givenTestClassSetupandTestMethodSetupparameterization, the framework calls thetestSizemethod 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 thetestRepeatablemethod in amethodsblock with theTestandParameterCombination = '成对'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 givenTestClassSetupandTestMethodSetupparameterization, the framework calls thetestRepeatablemethod 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 thetestClassmethod in amethodsblock with theTestattribute. Because theParameterCombinationattribute 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 fromrandis the same as the expected class. For a givenTestClassSetupandTestMethodSetupparameterization, the framework calls thetestClassmethod 3×3×2 = 18 times to ensure testing with each combination ofdim1,dim2, andtypeparameter values.

Create Suite from Test Class

At the command prompt, create a suite from theTestRandclass.

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 givenTestClassSetupandTestMethodSetupparameterization, the framework creates 3+10+18 = 31 test elements. These 31 elements are called for eachTestMethodSetupparameterization (resulting in 3×31 = 93 test elements for eachTestClassSetupparameterization). There are threeTestClassSetupparameterizations; 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 theseedproperty is not particularly meaningful (value1). The testing framework provided this name because theseedproperty is specified as a cell array. For a more meaningful name, define theseedproperty 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 theTestRandclass, you can construct the same filtered suite using theselectIfmethod.

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 thetestRepeatablemethod.

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 theTestRandclass that use the'double'parameter name.

runtests('TestRand','ParameterName','double');
Running TestRand .......... .......... .......... .......... .......... .......... .......... .......... . Done TestRand __________

See Also

||

Related Topics