This example shows how to create a custom plugin that counts the number of passing and failing assertions when running a specified test suite. The plugin prints a brief summary at the end of the testing.
In a file in your working folder, create a new class,
AssertionCountingPlugin
, that inherits from the
matlab.unittest.plugins.TestRunnerPlugin
class. For a
complete version of the code for an AssertionCountingPlugin
,
see "AssertionCountingPlugin Class Definition Summary".
Keep track of the number of passing and failing assertions. Within a
properties
block, create
NumPassingAssertions
and
NumFailingAssertions
properties to pass the data between
methods.
properties
NumPassingAssertions = 0;
NumFailingAssertions = 0;
end
Implement the runTestSuite
method in a
methods
block with protected
access.
methods (Access = protected) function runTestSuite(plugin, pluginData) suiteSize = numel(pluginData.TestSuite); fprintf('## Running a total of %d tests\n', suiteSize) plugin.NumPassingAssertions = 0; plugin.NumFailingAssertions = 0; runTestSuite@matlab.unittest.plugins.TestRunnerPlugin(... plugin, pluginData); fprintf('## Done running tests\n') plugin.printAssertionSummary() end end
The test framework evaluates this method one time. It displays information
about the total number of tests, initializes the assertion count, and invokes
the superclass method. After the framework completes evaluating the superclass
method, the runTestSuite
method displays the assertion count
summary.
Add listeners to AssertionPassed
and
AssertionFailed
events to count the assertions. To add
these listeners, extend the methods that the test framework uses to create the
test content. The test content comprises TestCase
instances
for each Test
element, class-level
TestCase
instances for the
TestClassSetup
and TestClassTeardown
methods, and Fixture
instances that are used when a
TestCase
class has the
SharedTestFixtures
attribute.
Invoke the corresponding superclass method when you override the creation methods. The creation methods return the content that the test framework creates for each of their respective contexts. When implementing one of these methods, pass this argument out of your own implementation, and add the listeners required by this plugin.
Add these creation methods to a methods
block with
protected
access.
methods (Access = protected) function fixture = createSharedTestFixture(plugin, pluginData) fixture = createSharedTestFixture@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); fixture.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); fixture.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end function testCase = createTestClassInstance(plugin, pluginData) testCase = createTestClassInstance@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); testCase.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); testCase.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end function testCase = createTestMethodInstance(plugin, pluginData) testCase = createTestMethodInstance@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); testCase.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); testCase.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end end
Extend runTest
to display the name of each test at run
time. Include this function in a methods
block with
protected
access. Like all plugin methods, when you
override this method you must invoke the corresponding superclass method.
methods (Access = protected) function runTest(plugin, pluginData) fprintf('### Running test: %s\n', pluginData.Name) runTest@matlab.unittest.plugins.TestRunnerPlugin(... plugin, pluginData); end end
In a methods
block with private
access,
define three helper functions. These functions increment the number of passing
or failing assertions, and print out the assertion count summary.
methods (Access = private) function incrementPassingAssertionsCount(plugin) plugin.NumPassingAssertions = plugin.NumPassingAssertions + 1; end function incrementFailingAssertionsCount(plugin) plugin.NumFailingAssertions = plugin.NumFailingAssertions + 1; end function printAssertionSummary(plugin) fprintf('%s\n', repmat('_', 1, 30)) fprintf('Total Assertions: %d\n', ... plugin.NumPassingAssertions + plugin.NumFailingAssertions) fprintf('\t%d Passed, %d Failed\n', ... plugin.NumPassingAssertions, plugin.NumFailingAssertions) end end
classdef AssertionCountingPlugin < ... matlab.unittest.plugins.TestRunnerPlugin properties NumPassingAssertions = 0; NumFailingAssertions = 0; end methods (Access = protected) function runTestSuite(plugin, pluginData) suiteSize = numel(pluginData.TestSuite); fprintf('## Running a total of %d tests\n', suiteSize) plugin.NumPassingAssertions = 0; plugin.NumFailingAssertions = 0; runTestSuite@matlab.unittest.plugins.TestRunnerPlugin(... plugin, pluginData); fprintf('## Done running tests\n') plugin.printAssertionSummary() end function fixture = createSharedTestFixture(plugin, pluginData) fixture = createSharedTestFixture@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); fixture.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); fixture.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end function testCase = createTestClassInstance(plugin, pluginData) testCase = createTestClassInstance@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); testCase.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); testCase.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end function testCase = createTestMethodInstance(plugin, pluginData) testCase = createTestMethodInstance@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); testCase.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); testCase.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end function runTest(plugin, pluginData) fprintf('### Running test: %s\n', pluginData.Name) runTest@matlab.unittest.plugins.TestRunnerPlugin(... plugin, pluginData); end end methods (Access = private) function incrementPassingAssertionsCount(plugin) plugin.NumPassingAssertions = plugin.NumPassingAssertions + 1; end function incrementFailingAssertionsCount(plugin) plugin.NumFailingAssertions = plugin.NumFailingAssertions + 1; end function printAssertionSummary(plugin) fprintf('%s\n', repmat('_', 1, 30)) fprintf('Total Assertions: %d\n', ... plugin.NumPassingAssertions + plugin.NumFailingAssertions) fprintf('\t%d Passed, %d Failed\n', ... plugin.NumPassingAssertions, plugin.NumFailingAssertions) end end end
In your working folder, create the file ExampleTest.m
containing the following test class.
classdef ExampleTest < matlab.unittest.TestCase methods(Test) function testOne(testCase) % Test fails testCase.assertEqual(5, 4) end function testTwo(testCase) % Test passes testCase.verifyEqual(5, 5) end function testThree(testCase) % Test passes testCase.assertEqual(7*2, 14) end end end
At the command prompt, create a test suite from the
ExampleTest
class.
import matlab.unittest.TestSuite import matlab.unittest.TestRunner suite = TestSuite.fromClass(?ExampleTest);
Create a test runner with no plugins. This code creates a silent runner and provides you with complete control over the installed plugins.
runner = TestRunner.withNoPlugins;
Run the tests.
result = runner.run(suite);
Add AssertionCountingPlugin
to the runner and run the
tests.
runner.addPlugin(AssertionCountingPlugin) result = runner.run(suite);
## Running a total of 3 tests ### Running test: ExampleTest/testOne ### Running test: ExampleTest/testTwo ### Running test: ExampleTest/testThree ## Done running tests ______________________________ Total Assertions: 2 1 Passed, 1 Failed
addlistener
| matlab.unittest.TestCase
| matlab.unittest.TestRunner
| matlab.unittest.fixtures.Fixture
| matlab.unittest.plugins.OutputStream
| matlab.unittest.plugins.TestRunnerPlugin