Use Parameters in Class-Based Tests - MATLAB & Simulink (original) (raw)

Often, you need to run a series of tests that are different only in terms of test data. For example, you might want to test that a function produces the expected outputs for different inputs. In this case, the test logic is the same and the only difference between tests is the actual and expected values for each function call. With parameterized testing, you can implement code to iteratively run tests using different data values. When a method is parameterized, the testing framework automatically invokes the method for each parameter value. Therefore, you are not required to implement a separate method for each value.

The testing framework enables you to parameterize your test class at different levels. Additionally, when you call a test class method with multiple parameters, you can specify how the method should be invoked for different combinations of the parameters.

How to Write Parameterized Tests

Classes that derive from the matlab.unittest.TestCase class can implement test parameterization using framework-specific property and method attributes. To provide data as parameters in your class-based test, specify the data using a properties block with an appropriate parameterization attribute. Then, pass the parameterization property as an input argument to one or more methods.

For example, consider the SampleTest class. The class defines a parameterized test because it specifies properties within aproperties block with the TestParameter attribute. The properties are passed to Test methods and are used to perform qualifications.

classdef SampleTest < matlab.unittest.TestCase properties (TestParameter) numericArray = {int16(1),single(zeros(1,4)),magic(3)}; functionHandle = {@false,@() size([])}; end methods (Test) function test1(testCase,numericArray) testCase.verifyNotEmpty(numericArray) end function test2(testCase,functionHandle) testCase.verifyWarningFree(functionHandle) end end end

The test class results in a parameterized test suite with five elements.

suite = testsuite("SampleTest"); {suite.Name}'

ans =

5×1 cell array

{'SampleTest/test1(numericArray=int16_1)'          }
{'SampleTest/test1(numericArray=1x4_single)'       }
{'SampleTest/test1(numericArray=3x3_double)'       }
{'SampleTest/test2(functionHandle=@false)'         }
{'SampleTest/test2(functionHandle=function_handle)'}

Specify the value of a parameterization property as a nonempty cell array or scalar structure with at least one field. The testing framework uses the property value to specify parameter names and values in the test suite:

Note

If you have a MATLAB® Test™ license, you can set a parameterization property to amatlabtest.parameters.BaselineParameter object for baseline testing. For more information, see Create Baseline Tests for MATLAB Code (MATLAB Test). (since R2024b)

How to Initialize Parameterization Properties

When you define a parameterization property, you must initialize the property so that MATLAB can generate parameter names and values. You can initialize the property at either test class load time or test suite creation time:

Note

Once you assign a value to a parameterization property, do not modify it. For example, when you initialize a parameterization property using a default value, you cannot use a TestParameterDefinition method to overwrite the default value.

A parameter might be used by several unit tests. Tests using the same parameter must run independently, without accidentally affecting one another. In addition, a running test must not affect subsequent reruns of the same test. To ensure test run independence, initialize your parameterization properties with value objects. Using handle objects (such as MATLAB graphics objects) as parameter values is not recommended. For more information about the behavior of value and handle objects, see Comparison of Handle and Value Classes.

If you need to test handle objects in your parameterized test, consider constructing them indirectly by using function handles as parameter values and invoking those function handles in tests. For example, write a parameterized test to test the default current point of figures created with thefigure and uifigure functions.

classdef FigureTest < matlab.unittest.TestCase properties (TestParameter) figureType = {@figure,@uifigure}; end methods (Test) function defaultCurrentPoint(testCase,figureType) fig = figureType(); testCase.addTeardown(@close,fig) cp = fig.CurrentPoint; testCase.verifyEqual(cp,[0 0]) end end end

Specify Parameterization Level

You can parameterize a test class at three levels: class setup, method setup, and test. Parameterizing at each level requires the parameterization properties to have a specific property attribute. For example, at the highest level, aTestClassSetup method can be parameterized using a property defined in a properties block with theClassSetupParameter attribute. At the lowest level, aTest method can be parameterized using a property defined in a properties block with the TestParameter attribute.

This table shows different parameterization levels and the required method and property attributes for each level.

Parameterization Level Parameterization Definition Accessible Parameterization Properties
Method Attribute Property Attribute
Class-setup level TestClassSetup ClassSetupParameter ClassSetupParameter
Method-setup level TestMethodSetup MethodSetupParameter MethodSetupParameter andClassSetupParameter
Test level Test TestParameter TestParameter,MethodSetupParameter, andClassSetupParameter

A parameterized method can access parameterization properties depending on the level at which the method is defined:

For an example of how to parameterize a test class at different levels, see Create Advanced Parameterized Test.

Specify How Parameters Are Combined

When you pass more than one parameterization property to a method, you can use theParameterCombination method attribute to specify how parameters are combined. The testing framework invokes the method for the specified combinations.

This table shows different parameter combination strategies.

ParameterCombination Attribute Value Method Invocation
"exhaustive" (default) Methods are invoked for all combinations of parameter values. The testing framework uses this default combination if you do not specify the ParameterCombination attribute.
"sequential" Methods are invoked with corresponding parameter values. The parameterization properties must specify the same number of parameter values. For example, if a method is provided with two parameterization properties and each property specifies three parameter values, then the framework invokes the method three times.
"pairwise" Methods are invoked for every pair of parameter values at least once. Compared with the exhaustive combination, the pairwise combination typically results in fewer tests and therefore faster test execution.For example, this test uses the pairwise combination to test the size of different matrices.classdef ZerosTest < matlab.unittest.TestCase properties (TestParameter) rowCount = struct("r1",1,"r2",2,"r3",3); columnCount = struct("c1",2,"c2",3,"c3",4); type = {'single','double','uint16'}; end methods (Test,ParameterCombination="pairwise") function testSize(testCase,rowCount,columnCount,type) testCase.verifySize(zeros(rowCount,columnCount,type), ... [rowCount columnCount]) end end endCreate a test suite from the class. One possible outcome contains the ten elements listed below.suite = testsuite("ZerosTest"); {suite.Name}'ans = 10×1 cell array {'ZerosTest/testSize(rowCount=r1,columnCount=c1,type=single)'} {'ZerosTest/testSize(rowCount=r1,columnCount=c2,type=double)'} {'ZerosTest/testSize(rowCount=r1,columnCount=c3,type=uint16)'} {'ZerosTest/testSize(rowCount=r2,columnCount=c1,type=double)'} {'ZerosTest/testSize(rowCount=r2,columnCount=c2,type=single)'} {'ZerosTest/testSize(rowCount=r2,columnCount=c3,type=single)'} {'ZerosTest/testSize(rowCount=r3,columnCount=c1,type=uint16)'} {'ZerosTest/testSize(rowCount=r3,columnCount=c2,type=single)'} {'ZerosTest/testSize(rowCount=r3,columnCount=c3,type=double)'} {'ZerosTest/testSize(rowCount=r2,columnCount=c2,type=uint16)'}The testing framework guarantees that thetestSize method is invoked for every combination of parameter values specified by any two properties. For instance, for the rowCount andcolumnCount properties, this table shows the TestSuite array indices corresponding to parameter value combinations. Every combination is represented by at least one Test element.—columnCount Propertyc1c2c3rowCount Propertyr1123r245, 106r3789While the framework guarantees that tests are created for every pair of values at least once, you should not rely on the suite size, ordering, or specific set of test suite elements.
"_n_-wise" Methods are invoked for every_n_-tuple of parameter values at least once (requires MATLAB Test). You can specify_n_ as an integer between 2 and 10. For example, specify the attribute as"4-wise" to invoke a method for every quadruple of parameter values at least once.You can use the "2-wise" and"pairwise" attribute values interchangeably. The"_n_-wise" parameter combination generalizes the pairwise combination, and typically results in fewer tests and therefore faster test execution compared with the exhaustive combination. While the framework guarantees that tests are created for every_n_-tuple of values at least once, you should not rely on the suite size, ordering, or specific set of test suite elements.

You can combine parameters at the class-setup, method-setup, and test levels. For example, use the two method attributesTestMethodSetup,ParameterCombination="sequential" to specify sequential combination of the method-setup-level parameters defined in theproperties block with theMethodSetupParameter attribute.

For examples of how to combine test parameters, see Create Basic Parameterized Test and Create Advanced Parameterized Test.

Use External Parameters in Tests

When you create a parameterized test, you can redefine the parameters by injecting inputs into your class-based test. To provide data that is defined outside of the test file, create a Parameter instance and use the ExternalParameter name-value argument when creating your test suite. For more information, see Use External Parameters in Parameterized Test.

See Also

Classes

Namespaces

Topics