创建自定义插件
此示例演示如何创建一个自定义插件,以便统计在 TestRunner
运行测试套件时的通过和失败断言数。该插件在测试结束时输出简短摘要。为了扩展 TestRunner
,该插件会创建 matlab.unittest.plugins.TestRunnerPlugin
类的子类并覆盖所选方法。
创建 AssertionCountingPlugin 类
在当前文件夹中的文件中,创建自定义插件类 AssertionCountingPlugin
,该类继承自 TestRunnerPlugin
类。有关 AssertionCountingPlugin
的完整代码,请参阅 AssertionCountingPlugin 类定义总结。
要跟踪通过和失败断言数,请编写 properties
代码块以定义两个只读属性 NumPassingAssertions
和 NumFailingAssertions
。
properties (SetAccess = private) NumPassingAssertions NumFailingAssertions end
扩展 TestSuite 的运行
编写具有 protected
访问权限的 methods
代码块以实现 runTestSuite
方法。
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
测试框架对此方法进行一次计算。它显示关于测试总数的信息,初始化插件用于生成文本输出的属性,并调用超类方法。在框架完成对超类方法的计算后,runTestSuite
方法通过调用辅助方法 printAssertionSummary
(请参阅定义辅助方法)来显示断言计数摘要。
扩展共享测试脚手架和 TestCase 实例的创建
将侦听程序添加到 AssertionPassed
和 AssertionFailed
事件以统计断言数。要添加这些侦听程序,请扩展测试框架用于创建测试内容的方法。测试内容包括每个 Test
元素的 TestCase
实例,TestClassSetup
和 TestClassTeardown
方法的类级别 TestCase
实例,以及在 TestCase
类具有 SharedTestFixtures
属性时使用的 Fixture
实例。
在覆盖创建方法时调用相应的超类方法。这些创建方法返回测试框架针对其各自上下文创建的内容。当使用 incrementPassingAssertionsCount
和 incrementFailingAssertionsCount
辅助方法实现上述方法时,将插件所需的侦听程序添加到返回的 Fixture
或 TestCase
实例。
将这些创建方法添加到具有 protected
访问权限的 methods
代码块。
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
扩展单个测试套件元素的运行
扩展 runTest
以在运行时显示每个测试的名称。将此方法添加到具有 protected
访问权限的 methods
代码块。像所有插件方法一样,runTest
方法要求您调用对应的超类方法。
methods (Access = protected) function runTest(plugin, pluginData) fprintf('### Running test: %s\n', pluginData.Name) runTest@matlab.unittest.plugins.TestRunnerPlugin(... plugin, pluginData); end end
定义辅助方法
在具有 private
访问权限的 methods
块中,定义三个辅助方法。这些方法累加通过或失败断言数,并输出断言计数摘要。
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
AssertionCountingPlugin 类定义总结
以下代码提供 AssertionCountingPlugin
的完整内容。
classdef AssertionCountingPlugin < ... matlab.unittest.plugins.TestRunnerPlugin properties (SetAccess = private) NumPassingAssertions NumFailingAssertions 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
创建示例测试类
在当前文件夹中,创建一个名为 ExampleTest.m
的文件,其中包含以下测试类。
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
将插件添加到 TestRunner 并运行测试
在命令提示符下,基于 ExampleTest
类创建测试套件。
import matlab.unittest.TestSuite import matlab.unittest.TestRunner suite = TestSuite.fromClass(?ExampleTest);
创建一个没有插件的 TestRunner
实例。此代码创建一个静默运行程序,以便您控制安装的插件。
runner = TestRunner.withNoPlugins;
运行测试。
result = runner.run(suite);
将 AssertionCountingPlugin
添加到运行程序并运行测试。
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
另请参阅
matlab.unittest.plugins.TestRunnerPlugin
| matlab.automation.streams.OutputStream
| matlab.unittest.TestCase
| matlab.unittest.TestRunner
| matlab.unittest.fixtures.Fixture
| addlistener