Create Advanced Custom Fixture - MATLAB & Simulink (original) (raw)
This example shows how to create a custom fixture that changes the output display format for numeric values. You can apply the fixture to a single test class or share the fixture across multiple test classes. After testing, the fixture restores the display format to its original state.
Create NumericFormatFixture
Class
In a file named NumericFormatFixture.m
in your current folder, create the NumericFormatFixture
class by deriving from the matlab.unittest.fixtures.Fixture interface. Because you want to pass the fixture a numeric format, add aFormat
property to your class.
properties (SetAccess=immutable)
Format (1,1) string
end
Add Fixture Constructor
In a methods
block in your class, define a constructor that sets the Format
property.
methods
function fixture = NumericFormatFixture(fmt)
fixture.Format = fmt;
end
end
Implement setup
Method
Subclasses of the Fixture
interface must implement the setup method, which makes changes to the environment when the testing framework sets up the fixture. To restore the environment when the framework tears down the fixture, you can call theaddTeardown method within thesetup
method.
In a methods
block, implement the setup
method to change the numeric format to the format specified during fixture construction and to restore the format to its original state after testing. To provide descriptive information when the framework sets up and tear downs the fixture, set the SetupDescription
andTeardownDescription
properties within the method.
methods
function setup(fixture)
originalFormat = format;
fixture.addTeardown(@format,originalFormat)
format(fixture.Format)
fixture.SetupDescription = "Set the numeric format to " + ...
fixture.Format + ".";
fixture.TeardownDescription = ...
"Restored the numeric format to " + ...
originalFormat.NumericFormat + ".";
end
end
Implement isCompatible
Method
Implement the isCompatible method in yourFixture
subclass if the fixture is configurable (for instance, if its class constructor accepts input arguments). In this example, because you set the Format
property using the class constructor, you must implement isCompatible
.
The testing framework calls isCompatible
to determine whether instances of the same Fixture
subclass correspond to the same shared test fixture state. The information about fixture compatibility helps the framework decide when to perform teardown and setup actions. TwoNumericFormatFixture
instances make the same change to the environment when their Format
properties are equal. Specify this compatibility definition by implementing the isCompatible
method in a methods
block with protected
access.
methods (Access=protected)
function tf = isCompatible(fixture1,fixture2)
tf = fixture1.Format == fixture2.Format;
end
end
Fixture Class Definition
This code provides the complete contents of theNumericFormatFixture
class.
classdef NumericFormatFixture < matlab.unittest.fixtures.Fixture properties (SetAccess=immutable) Format (1,1) string end
methods
function fixture = NumericFormatFixture(fmt)
fixture.Format = fmt;
end
function setup(fixture)
originalFormat = format;
fixture.addTeardown(@format,originalFormat)
format(fixture.Format)
fixture.SetupDescription = "Set the numeric format to " + ...
fixture.Format + ".";
fixture.TeardownDescription = ...
"Restored the numeric format to " + ...
originalFormat.NumericFormat + ".";
end
end
methods (Access=protected)
function tf = isCompatible(fixture1,fixture2)
tf = fixture1.Format == fixture2.Format;
end
end
end
Apply Custom Fixture to Single Test Class
In a file named ExampleTest.m
in your current folder, create the ExampleTest
class that applies the custom fixture and verifies that a numeric value is displayed in the expected format. To simplify this example, the actual value is produced by a call to the formattedDisplayText function. In practice, you test user-defined code.
classdef ExampleTest < matlab.unittest.TestCase methods (Test) function formatTest(testCase) testCase.applyFixture(NumericFormatFixture("bank")) actual = strtrim(formattedDisplayText(pi)); expected = "3.14"; testCase.verifyEqual(actual,expected) end end end
Run the ExampleTest
class. The testing framework sets up the fixture, which changes the display format to the currency format. Once the test run is complete, the framework tears down the fixture, which restores the original display format. In this example, the test passes.
Running ExampleTest . Done ExampleTest
Apply Custom Fixture as Shared Fixture
In your current folder, create three test classes that each use an instance ofNumericFormatFixture
as a shared test fixture.
In a file named TestA.m
, create the TestA
class.
classdef (SharedTestFixtures={NumericFormatFixture("bank")}) ... TestA < matlab.unittest.TestCase methods (Test) function formatTest(testCase) actual = strtrim(formattedDisplayText(pi)); expected = "3.14"; testCase.verifyEqual(actual,expected) end end end
In a file named TestB.m
, create the TestB
class.
classdef (SharedTestFixtures={NumericFormatFixture("bank")}) ... TestB < matlab.unittest.TestCase methods (Test) function formatTest(testCase) actual = strtrim(formattedDisplayText(100/3)); expected = "33.33"; testCase.verifyEqual(actual,expected) end end end
In a file named TestC.m
, create the TestC
class.
classdef (SharedTestFixtures={NumericFormatFixture("hex")}) ... TestC < matlab.unittest.TestCase methods (Test) function formatTest(testCase) actual = strtrim(formattedDisplayText(1)); expected = "3ff0000000000000"; testCase.verifyEqual(actual,expected) end end end
The TestA
and TestB
classes are assigned shared fixtures that make the same change to the environment. On the other hand, theTestC
class is assigned a fixture that enforces a different numeric format. According to the implementation of theisCompatible
method in this example, the testing framework finds the fixtures on TestA
and TestB
compatible. However, it finds the fixture on TestC
incompatible with the other fixtures.
The information about fixture compatibility helps the framework decide when to perform teardown and setup actions. If you run TestA
,TestB
, and TestC
as part of the same test suite, the framework does not tear down the fixture when switching fromTestA
to TestB
because both classes require the same environment. However, when switching from TestB
toTestC
, the framework tears down the existing fixture and sets up a fresh fixture required by TestC
. In this example, all the tests pass.
runtests(["TestA" "TestB" "TestC"]);
Setting up NumericFormatFixture Done setting up NumericFormatFixture: Set the numeric format to bank.
Running TestA . Done TestA
Running TestB . Done TestB
Tearing down NumericFormatFixture Done tearing down NumericFormatFixture: Restored the numeric format to short.
Setting up NumericFormatFixture Done setting up NumericFormatFixture: Set the numeric format to hex.
Running TestC . Done TestC
Tearing down NumericFormatFixture Done tearing down NumericFormatFixture: Restored the numeric format to short.
Alternative Approach to Calling addTeardown
in setup
Method
An alternative approach to calling the addTeardown
method within the setup
method is to implement a separate teardown method. This code shows how to recreate the NumericFormatFixture
class by implementing both the setup
and teardown
methods. Note that the alternative class definition contains an additional property,OriginalFormat
, to pass information about the original format to the teardown
method.
classdef NumericFormatFixture < matlab.unittest.fixtures.Fixture properties (SetAccess=immutable) Format (1,1) string end
properties (Access=private)
OriginalFormat
end
methods
function fixture = NumericFormatFixture(fmt)
fixture.Format = fmt;
end
function setup(fixture)
fixture.OriginalFormat = format().NumericFormat;
format(fixture.Format)
fixture.SetupDescription = "Set the numeric format to " + ...
fixture.Format + ".";
end
function teardown(fixture)
format(fixture.OriginalFormat)
fixture.TeardownDescription = ...
"Restored the numeric format to " + ...
fixture.OriginalFormat + ".";
end
end
methods (Access=protected)
function tf = isCompatible(fixture1,fixture2)
tf = fixture1.Format == fixture2.Format;
end
end
end
See Also
matlab.unittest.fixtures.Fixture | matlab.unittest.TestCase | format