Use External Parameters in Parameterized Test - MATLAB & Simulink (original) (raw)
You can inject variable inputs into your existing class-based test. To provide test data that is defined outside the test file and that should be used iteratively by the test (via parameterized testing), create an array of Parameter
instances, and then use the ExternalParameters
name-value argument with TestSuite
creation methods such as fromClass
.
Create the cleanData
function. The function accepts an array, vectorizes the array, removes 0
, NaN
, and Inf
, and then sorts the array.
function Y = cleanData(X) Y = X(:); % Vectorize array Y = rmmissing(Y); % Remove NaN % Remove 0 and Inf idx = (Y==0 | Y==Inf); Y = Y(~idx); % If array is empty, set to eps if isempty(Y) Y = eps; end Y = sort(Y); % Sort vector end
Create a parameterized test to test the cleanData
function. The test repeats each of the four Test
methods for the two data sets that are defined in the properties
block.
classdef TestClean < matlab.unittest.TestCase
properties (TestParameter)
Data = struct("clean",[5 3 9;1 42 5;32 5 2], ...
"needsCleaning",[1 13;NaN 0;Inf 42]);
end
methods (Test)
function classCheck(testCase,Data)
act = cleanData(Data);
testCase.assertClass(act,"double")
end
function sortCheck(testCase,Data)
act = cleanData(Data);
testCase.verifyTrue(issorted(act))
end
function finiteCheck(testCase,Data)
import matlab.unittest.constraints.IsFinite
act = cleanData(Data);
testCase.verifyThat(act,IsFinite)
end
function noZeroCheck(testCase,Data)
import matlab.unittest.constraints.EveryElementOf
import matlab.unittest.constraints.IsEqualTo
act = cleanData(Data);
testCase.verifyThat(EveryElementOf(act),~IsEqualTo(0))
end
end
end
Run the tests. The framework runs the eight parameterized tests using the data defined in the test file.
import matlab.unittest.TestSuite suite1 = TestSuite.fromClass(?TestClean); results = suite1.run; table(results)
Running TestClean ........ Done TestClean
ans =
8×6 table
Name Passed Failed Incomplete Duration Details
_____________________________________________ ______ ______ __________ _________ ____________
{'TestClean/classCheck(Data=clean)' } true false false 0.66469 {1×1 struct}
{'TestClean/classCheck(Data=needsCleaning)' } true false false 0.0066959 {1×1 struct}
{'TestClean/sortCheck(Data=clean)' } true false false 0.0039298 {1×1 struct}
{'TestClean/sortCheck(Data=needsCleaning)' } true false false 0.003343 {1×1 struct}
{'TestClean/finiteCheck(Data=clean)' } true false false 0.055924 {1×1 struct}
{'TestClean/finiteCheck(Data=needsCleaning)'} true false false 0.0017951 {1×1 struct}
{'TestClean/noZeroCheck(Data=clean)' } true false false 0.90772 {1×1 struct}
{'TestClean/noZeroCheck(Data=needsCleaning)'} true false false 0.007801 {1×1 struct}
Create a data set external to the test file.
Create an array of Parameter
instances from the external data set. The fromData
method accepts the name of the parameterization property from the properties
block in TestClean
and the new data as a cell array (or structure).
import matlab.unittest.parameters.Parameter newData = {A}; param = Parameter.fromData("Data",newData);
Create a new test suite using the external parameters. The framework appends the characters #ext
to the end of the parameter names, indicating that the parameters are defined externally.
suite2 = TestSuite.fromClass(?TestClean,"ExternalParameters",param); {suite2.Name}'
ans =
4×1 cell array
{'TestClean/classCheck(Data=2x3_double#ext)' }
{'TestClean/sortCheck(Data=2x3_double#ext)' }
{'TestClean/finiteCheck(Data=2x3_double#ext)'}
{'TestClean/noZeroCheck(Data=2x3_double#ext)'}
To have full control over parameter names in the suite, define the parameters using a structure. Then, run the tests.
newData = struct("commandLineData",A); param = Parameter.fromData("Data",newData); suite2 = TestSuite.fromClass(?TestClean,"ExternalParameters",param); {suite2.Name}' results = suite2.run;
ans =
4×1 cell array
{'TestClean/classCheck(Data=commandLineData#ext)' }
{'TestClean/sortCheck(Data=commandLineData#ext)' }
{'TestClean/finiteCheck(Data=commandLineData#ext)'}
{'TestClean/noZeroCheck(Data=commandLineData#ext)'}
Running TestClean .... Done TestClean
Create another data set that is stored in an ASCII-delimited file.
B = rand(3); B(2,4) = 0; writematrix(B,"myFile.dat") clear B
Create parameters from the stored data set and A
, and then create a test suite.
newData = struct("commandLineData",A,"storedData",readmatrix("myFile.dat")); param2 = Parameter.fromData("Data",newData); suite3 = TestSuite.fromClass(?TestClean,"ExternalParameters",param2);
To run the tests using parameters defined in the test file and externally, concatenate the test suites. View the suite element names and run the tests.
suite = [suite1 suite3]; {suite.Name}' results = suite.run;
ans =
16×1 cell array
{'TestClean/classCheck(Data=clean)' }
{'TestClean/classCheck(Data=needsCleaning)' }
{'TestClean/sortCheck(Data=clean)' }
{'TestClean/sortCheck(Data=needsCleaning)' }
{'TestClean/finiteCheck(Data=clean)' }
{'TestClean/finiteCheck(Data=needsCleaning)' }
{'TestClean/noZeroCheck(Data=clean)' }
{'TestClean/noZeroCheck(Data=needsCleaning)' }
{'TestClean/classCheck(Data=commandLineData#ext)' }
{'TestClean/classCheck(Data=storedData#ext)' }
{'TestClean/sortCheck(Data=commandLineData#ext)' }
{'TestClean/sortCheck(Data=storedData#ext)' }
{'TestClean/finiteCheck(Data=commandLineData#ext)'}
{'TestClean/finiteCheck(Data=storedData#ext)' }
{'TestClean/noZeroCheck(Data=commandLineData#ext)'}
{'TestClean/noZeroCheck(Data=storedData#ext)' }
Running TestClean ........ Done TestClean
Running TestClean ........ Done TestClean
See Also
matlab.unittest.TestSuite | matlab.unittest.parameters.Parameter.fromData