Package: matlab.test.behavior
Superclasses: matlab.unittest.TestCase
Test if class satisfies contract for missing
values
To test if the missing
value for your class satisfies the missing contract in MATLAB®, create a test class that derives from the
matlab.test.behavior.Missing
class. If your class represents a data type and
you want MATLAB to treat missing
values of your class similar to built-in
classes, ensure that your class satisfies the missing
contract.
Typically, you use the behavior test as part of a test-driven development workflow. If you
want the missing value for your class to satisfy the missing contract with MATLAB, write the behavior test and modify the class under test until the test results
are as you expect. For example, if your class supports comparisons and ordering and is usable
as a missing value indicator, all tests should pass. If your class does not support ordering,
set the SupportsOrdering
property to false
and expect
that MATLAB filters out tests associated with ordering.
Your behavior test only must derive from matlab.test.behavior.Missing
and
define the abstract properties. However, since matlab.test.behavior.Missing
is
a subclass of matlab.unittest.TestCase
, you can use the functionality of the
Unit Testing Framework.
Abstract | true |
HandleCompatible | true |
For information on class attributes, see Class Attributes.
Define values for all abstract
properties in the
properties
block of your test class.
MissingValue
— Missing value for class under testMissing value for class under test, specified as a valid MATLAB scalar value or an expression that returns a non-missing value.
Example: NaN
or missing
or '
'
SetAccess | public |
GetAccess | public |
Abstract | true |
PrototypeValue
— Non-missing value for class under testAny non-missing value for the class under test, specified as a valid MATLAB scalar value or an expression that returns a non-missing value. Typically,
if the class constructor returns a non-missing value,
PrototypeValue
is a call to the constructor.
Example: 0 or datetime
SetAccess | public |
GetAccess | public |
Abstract | true |
ClassesWithSupportedConversions
— Classes that can be converted to class under testList of classes that can be converted to the class under test, specified as a string array of class names.
If you can convert to the other class and then back to your class, then your class
has a supported conversion from the other class. For example, if
MyClass(OtherClass(missing)) == MyClass(missing)
than
OtherClass
is a class with supported conversions.
Example: "string"
or
["double","single"]
SetAccess | public |
GetAccess | public |
Abstract | true |
Data Types: string
If necessary, redefine values for concrete properties in a function in the
TestClassSetup
methods block of your test class.
SupportsComparison
— Class supports comparisontrue
(default) | false
Indicator that the class supports comparison, specified as true
or false
. A class that supports comparisons allows use of
==
and ~=
.
If you set SupportsComparison
to false
,
expect comparison and ordering tests to be filtered by assumption failure. MATLAB does not run the tests.
SetAccess | protected |
GetAccess | public |
Data Types: logical
SupportsOrdering
— logical scalar to control the run of <, >, and so forthtrue
(default) | false
Indicator that the class supports ordering, specified as true
or
false
. A class that supports ordering allows use of
<
, >
, <=
, and
>=
.
If you set SupportsOrdering
to false
, expect
associated tests to be filtered by assumption failure. MATLAB does not run the tests.
SetAccess | protected |
GetAccess | public |
Data Types: logical
UsableAsMissingIndicator
— Class is usable as missing value indicatortrue
(default) | false
Indicator that the class is usable as a missing value indicator to the
ismissing
function, specified as true
or
false
.
If you set UsableAsMissingIndicator
to
false
, expect associated tests to be filtered by assumption failure.
MATLAB does not run the tests.
SetAccess | protected |
GetAccess | public |
Data Types: logical
FillValue
— Value for growing arrayMissingValue
property (default) | valid MATLAB scalar valueThe fill value that your class uses for growing arrays, specified as a valid
MATLAB scalar value. By default, the value of FillValue
is
the same as the value of the MissingValue
property.
Example: 0
SetAccess | protected |
GetAccess | public |
Create the MyDataClass
class that can contain a
missing value. The class supports comparison and ordering, and the missing value
implementation should satisfy the missing contract in MATLAB. If you call the constructor with no inputs, it returns a missing
value.
classdef MyDataClass properties SomeData; MissingVal = false; end methods function obj = MyDataClass(value) if nargin m = size(value,1); n = size(value,2); for i = 1:m for j = 1:n if ismissing(value(i,j)) obj(i,j).MissingVal = true; else obj(i,j).SomeData = value(i,j); obj(i,j).MissingVal = false; end end end else obj.MissingVal = true; end end % Define ismissing behavior function m = ismissing(obj,v) if nargin > 1 m = isequaln(obj,v); else m = [obj.MissingVal]; end m = reshape(m,size(obj)); end end end
To create a simple test class that checks that MyDataClass
satisfies the missing value contract, subclass
matlab.test.behavior.Missing
. The test can use the functionality of the
unit testing framework, but MissingValueTest
is checking the missing
contract only.
classdef MissingValueTest < matlab.test.behavior.Missing properties MissingValue = MyDataClass; PrototypeValue = MyDataClass(7); ClassesWithSupportedConversions = []; end end
Run the tests and review the results. The tests for comparison, ordering, equality,
and using MyDataClass
as the second input to
ismissing
fail.
results = runtests('MissingValueTest');
Running MissingValueTest .... ================================================================================ Error occurred in MissingValueTest/comparison and it did not run to completion. --------- Error ID: --------- 'MATLAB:UndefinedFunction' -------------- Error Details: -------------- Undefined function 'eq' for input arguments of type 'MyDataClass'. Error in matlab.test.behavior.Missing/comparison (line 129) testCase.verifyFalse(testCase.MissingValue == testCase.MissingValue, getString(message('MATLAB:test:behavior:missing:EqualFalse'))); ================================================================================ . ================================================================================ Error occurred in MissingValueTest/ordering and it did not run to completion. --------- Error ID: --------- 'MATLAB:UndefinedFunction' -------------- Error Details: -------------- Undefined function 'lt' for input arguments of type 'MyDataClass'. Error in matlab.test.behavior.Missing/ordering (line 136) testCase.verifyFalse(testCase.MissingValue < testCase.MissingValue, getString(message('MATLAB:test:behavior:missing:LessThanFalse'))); ================================================================================ . ================================================================================ Verification failed in MissingValueTest/isequalRules. ---------------- Test Diagnostic: ---------------- isequal(MissingValue, MissingValue) must return false, because all missing values are unequal. --------------------- Framework Diagnostic: --------------------- verifyFalse failed. --> The value must evaluate to "false". Actual Value: logical 1 ------------------ Stack Information: ------------------ In <matlabroot>\toolbox\matlab\datatypes\+matlab\+test\+behavior\Missing.m (Missing.isequalRules) at 145 ================================================================================ ================================================================================ Verification failed in MissingValueTest/isequalRules. ---------------- Test Diagnostic: ---------------- isequaln(MissingValue, missing) must return true. --------------------- Framework Diagnostic: --------------------- verifyTrue failed. --> The value must evaluate to "true". Actual Value: logical 0 ------------------ Stack Information: ------------------ In <matlabroot>\toolbox\matlab\datatypes\+matlab\+test\+behavior\Missing.m (Missing.isequalRules) at 147 ================================================================================ . ================================================================================ Verification failed in MissingValueTest/IsMissing2ndInput. ---------------- Test Diagnostic: ---------------- ismissing(MissingValue, missing) must return true. --------------------- Framework Diagnostic: --------------------- verifyTrue failed. --> The value must evaluate to "true". Actual Value: logical 0 ------------------ Stack Information: ------------------ In <matlabroot>\toolbox\matlab\datatypes\+matlab\+test\+behavior\Missing.m (Missing.IsMissing2ndInput) at 154 ================================================================================ ... Done MissingValueTest __________ Failure Summary: Name Failed Incomplete Reason(s) ================================================================================= MissingValueTest/comparison X X Errored. --------------------------------------------------------------------------------- MissingValueTest/ordering X X Errored. --------------------------------------------------------------------------------- MissingValueTest/isequalRules X Failed by verification. --------------------------------------------------------------------------------- MissingValueTest/IsMissing2ndInput X Failed by verification.
Iteratively update MyDataClass
to satisfy the missing contract.
To satisfy comparison and ordering, define eq
,
ne
, lt
, gt
,
le
, and ge
in the methods
block of MyDataClass
.
% Class supports comparison function tf = eq(obj1,obj2) tf = ~any(ismissing([obj1 obj2])) && eq(obj1.SomeData,obj2.SomeData); end function tf = ne(obj1,obj2) tf = ~eq(obj1,obj2); end % Class supports ordering function tf = lt(obj1,obj2) tf = ~any(ismissing([obj1 obj2])) && lt(obj1.SomeData,obj2.SomeData); end function tf = gt(obj1,obj2) tf = lt(obj2,obj1); end function tf = le(obj1,obj2) tf = ~any(ismissing([obj1 obj2])) && ~gt(obj1,obj2); end function tf = ge(obj1,obj2) tf = le(obj2,obj1); end
Run the tests with a terse level output detail and review the results.
results = runtests('MissingValueTest','OutputDetail',1);
...... FAIL: MissingValueTest/isequalRules in Missing.isequalRules at 145 :: verifyFalse failed. FAIL: MissingValueTest/isequalRules in Missing.isequalRules at 147 :: verifyTrue failed. . FAIL: MissingValueTest/IsMissing2ndInput in Missing.IsMissing2ndInput at 154 :: verifyTrue failed. ...
Iteratively update MyDataClass
to satisfy the equality rules.
Define isqual
and isequaln
in the
methods
block of MyDataClass
.
% Class supports isequal/isequaln rules function tf = isequal(obj1,obj2) tf = eq(obj1,obj2); end function tf = isequaln(obj1,obj2) tf = all(ismissing([obj1 obj2])) || eq(obj1,obj2); end
Run the tests and review the results. The tests pass and
MyDataClass
satisfies the missing value contract.
results = runtests('MissingValueTest');
Running MissingValueTest .......... Done MissingValueTest __________
The behavior test asserts the following conditions are true.
The missing value in the MissingValue
property is the same
class as the value in the PrototypeValue
property.
The MissingValue
and PrototypeValue
values are scalar.
The ismissing
function called with the
MissingValue
value returns true
.
The ismissing
function called with the
PrototypeValue
value returns false
.
The behavior test verifies that converting the missing value to an instance of your
class returns the same value as the MissingValue
property.
Additionally, for each class that your class can convert, the behavior test verifies
conversion of missing values. For example, if you can convert between
OtherClass
and MyClass
, the behavior test verifies
that MyClass(OtherClass(missing)) == MyClass(missing)
. The
ClassesWithSupportedConversions
property indicates which classes
your class can convert.
Given an array of objects of your class, subscripted assignment tests verify that you can expand the array using the missing value and assign the missing value to a range of elements in the array.
Concatenation tests verify that arrays of objects of your class can be concatenated with missing values.
Equality tests verify that isequal
returns
false
for two missing values and isequaln
returns true
for two missing values.
SupportsComparison
By default, the behavior test assumes that your class supports comparison of values,
including missing values. Comparison tests verify that you implemented
==
and ~=
as MATLAB expects, with respect to
missing values.
The comparison of two missing values with ==
returns
false
.
The comparison of two missing values with ~=
returns
true
.
If your class does not support comparisons, set the
SupportsComparison
property to false
so
MATLAB does not run these tests. In this case, comparison tests are filtered as
assumption failures. Additionally, if SupportsComparison = false
,
MATLAB does not run the ordering tests.
SupportsOrdering
By default, the behavior test assumes that your class supports ordering of values,
including missing values. Ordering tests verify that you implemented
<
, >
, <=
, and
>=
as MATLAB expects, with respect to missing values. For missing values, MATLAB expects that all the ordering operations return
false
.
If your class supports ordering, to satisfy the behavior contract, it must also
support comparisons. If SupportsComparison = false
, MATLAB does not run the ordering tests or the comparison tests. In this case,
ordering tests are marked as assumption failures (filtered tests).
If your class does not support ordering, set the SupportsOrdering
property to false
so MATLAB does not run these tests. In this case, ordering tests are marked as
assumption failures (filtered tests).
UsableAsMissingIndicator
By default, the behavior test assumes that an instance of your class can be used as
the optional input argument to the ismissing
function that represents
the missing value indicator.
If your class is unable to be a missing value indicator, set the
UsableAsMissingIndicator
property to false
so
MATLAB does not run these tests. In this case, ordering tests are marked as
assumption failures (filtered tests).
FillValue
The behavior test verifies that when MATLAB grows an array of elements of your class, the new elements have the value
specified by the FillValue
property. By default, the
FillValue
property is the same as the
MissingValue
property. However, you can specify a different value
for FillValue
.