Class-Based Unit Tests
You can test your MATLAB® source code by creating unit tests within a test class that inherits
from the matlab.unittest.TestCase
class.
The TestCase
class is the superclass of all test classes in
MATLAB and provides an interface to write and identify test content,
including test fixture setup and teardown routines.
Write your class-based unit tests as Test
methods within your test class definition file. A Test
method is
a method defined in a methods
block with the
Test
attribute. Test
methods can use
qualifications for testing values and responding to failures. In addition to the
Test
attribute, TestCase
subclasses can
leverage a variety of framework-specific attributes to specify tests and test
fixtures. For example, you can use the TestMethodSetup
and
TestMethodTeardown
method attributes to specify setup and
teardown code for each test in your test class.
Test Class Definition
To write class-based tests, first create a class that derives from the
matlab.unittest.TestCase
class. Then, specify your unit tests by
adding methods to a methods
block with the
Test
attribute within your test class. For example, the
MyTestClass
class includes two tests (test1
and
test2
). The first input to a Test
method
must be a TestCase
object, which the test can ignore if its logic
does not require it. The TestCase
object passed to a
Test
method provides test-environment-specific information to
the corresponding test.
In addition, the MyTestClass
class uses framework-specific method
attributes to define the setup
and teardown
methods. The testing framework runs these methods before and after each test,
respectively. For more information about setup and teardown code in test classes,
see Write Setup and Teardown Code Using Classes.
classdef MyTestClass < matlab.unittest.TestCase methods (TestMethodSetup) function setup(testCase) % Setup code end end methods (TestMethodTeardown) function teardown(testCase) % Teardown code end end methods (Test) function test1(testCase) % Test code end function test2(testCase) % Test code end end end
Unit tests typically include qualifications for testing values and responding to
failures. For example, to test a function, a Test
method can
specify the actual and expected returned values of the function and then use a
qualification method to test for their equality. For illustrative purposes, the
PlusTest
test class has a Test
method for
testing the plus
function. (In practice, a test class tests
user-defined code.) The myTest
method calls the
verifyEqual
qualification method to verify that
plus(2,3)
produces the expected value 5
.
When creating your own test class, you have access to the full library of
qualifications in the matlab.unittest.qualifications
namespace. To determine which qualification to use, see Table of Verifications, Assertions, and Other Qualifications.
classdef PlusTest < matlab.unittest.TestCase methods (Test) function myTest(testCase) actual = plus(2,3); expected = 5; testCase.verifyEqual(actual,expected) end end end
For a simple example of how to write and run class-based unit tests, see Write Simple Test Case Using Classes.
How Test Classes Run
When you run class-based tests (for instance, results =
runtests(["TestClassA" "TestClassB" "TestClassC"])
), the testing
framework first divides the test classes into groups based on their shared test
fixtures. (Shared test fixtures are fixtures specified using the
SharedTestFixtures
attribute of TestCase
subclasses.) Each group includes test classes that have exactly the same shared test
fixtures. To minimize the required setup and teardown actions, the framework runs
the test classes in each group by setting up and tearing down their shared test
fixtures a single time. In other words, for each group, the framework:
Sets up the shared test fixtures before running any of the test classes in the group
Runs each test class in the group
Tears down the shared test fixtures after running all the test classes in the group
This diagram shows how the testing framework runs each test class in step 2.
The framework follows these steps when running a test class:
Create class-level
TestCase
object — The framework creates an object of the test class.Run class-level setup code — The framework uses the class-level
TestCase
object to run the class-level setup code specified in theTestClassSetup
methods
block. The class-levelTestCase
object reflects the updated environment as a result of the class-level setup code.Loop over tests:
Create method-level
TestCase
object — The framework creates a method-levelTestCase
object by copying the class-levelTestCase
object that reflects the environment after the execution of the class-level setup code. The framework then passes this object to theTestMethodSetup
,Test
, andTestMethodTeardown
methods of the test class.Note
To prevent a test from affecting the environment of other tests,
TestCase
instances passed to differentTest
methods are independent copies. In other words, modifications to the test case in aTest
method remain scoped to that method and do not propagate to otherTest
methods in the test class.Run method-level setup code — The framework uses the method-level
TestCase
object to run the method-level setup code specified in theTestMethodSetup
methods
block. The method-levelTestCase
object reflects the updated environment as a result of the method-level setup code.Run test — The framework uses the method-level
TestCase
object to run theTest
method corresponding to the test. If the test is parameterized, the framework uses the parameterization information to run the method.Run method-level teardown code — The framework uses the method-level
TestCase
object to run the method-level teardown code specified using a call to theaddTeardown
method in theTestMethodSetup
methods
block or in theTestMethodTeardown
methods
block.Delete method-level
TestCase
object — The framework discards the method-levelTestCase
object used to run the test and its corresponding method-level setup and teardown code.
Run class-level teardown code — The framework uses the class-level
TestCase
object to run the class-level teardown code specified using a call to theaddTeardown
method in theTestClassSetup
methods
block or in theTestClassTeardown
methods
block.Delete class-level
TestCase
object — The framework discards the class-levelTestCase
object used to run the tests in the test class.
Note
Uncaught errors and qualification failures can affect the test run workflow.
For instance, if an assumption failure occurs in the
TestClassSetup
or TestClassTeardown
methods
block, the testing framework marks the entire test
class as filtered and skips looping over the Test
methods.
Test Independence and Repeatability
Unit tests in a matlab.unittest.TestCase
subclass must run
independently, without unintentionally affecting one another. In addition, they must
be repeatable, which means that a running test must not affect subsequent reruns of
the same test. For test independence and repeatability, follow these best practices
when creating a test class:
If you add code to your test class for setting up the test environment, also include code to restore the environment to its original state by performing teardown actions symmetrically in the reverse order of their corresponding setup actions.
To access a global state, such as the MATLAB search path or output display format, use a method instead of a default property value.
To specify test parameter values, use value objects instead of handle objects.
For more information, see Write Independent and Repeatable Tests.
Features of Class-Based Tests
Class-based tests provide you with several advanced test authoring features and give you access to the full MATLAB unit testing framework functionality. For example, you can use advanced qualification features, including constraints, actual value proxies, tolerances, and test diagnostics, in your class-based tests. In addition, with class-based tests, you can:
Share fixtures among test classes. For more information, see Write Tests Using Shared Fixtures.
Group tests into categories and then run the tests with specified tags. For more information, see Tag Unit Tests.
Write parameterized tests to combine and execute tests on specified lists of parameters. For more information, see Use Parameters in Class-Based Tests.
Use subclassing and inheritance to share and reuse test content. For example, you can reuse the parameters and methods defined in a test class by deriving subclasses. For more information, see Hierarchies of Classes — Concepts.