编写用于保存诊断详细信息的插件
本示例演示如何创建自定义插件来保存诊断详细信息。该插件将侦听测试失败并保存诊断信息,以便您在框架完成测试后访问此信息。
创建插件
在工作文件夹下的文件中,创建从 matlab.unittest.plugins.TestRunnerPlugin
类继承的 myPlugin
类。在插件类中:
定义插件的
FailedTestData
属性,用于存储来自失败测试的信息。覆盖
TestRunnerPlugin
的默认createTestMethodInstance
方法,以侦听断言、致命断言和验证失败,以及记录相关信息。覆盖
TestRunnerPlugin
的默认runTestSuite
方法,以初始化FailedTestData
属性值。如果您没有初始化该属性值,则在每次使用同一测试运行程序运行测试时,失败测试信息都会附加到FailedTestData
属性。定义辅助函数
recordData
,以将关于测试失败的信息保存为表。
该插件保存 PluginData
和 QualificationEventData
对象中包含的信息。它还会保存失败类型和时间戳。
classdef DiagnosticRecorderPlugin < matlab.unittest.plugins.TestRunnerPlugin properties FailedTestData end methods (Access = protected) function runTestSuite(plugin, pluginData) plugin.FailedTestData = []; runTestSuite@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); end function testCase = createTestMethodInstance(plugin, pluginData) testCase = createTestMethodInstance@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); testName = pluginData.Name; testCase.addlistener('AssertionFailed', ... @(~,event)plugin.recordData(event,testName, 'Assertion')); testCase.addlistener('FatalAssertionFailed', ... @(~,event)plugin.recordData(event,testName, 'Fatal Assertion')); testCase.addlistener('VerificationFailed', ... @(~,event)plugin.recordData(event,testName, 'Verification')); end end methods (Access = private) function recordData(plugin,eventData,name,failureType) s.Name = {name}; s.Type = {failureType}; if isempty(eventData.TestDiagnosticResult) s.TestDiagnostics = 'TestDiagnostics not provided'; else s.TestDiagnostics = eventData.TestDiagnosticResult; end s.FrameworkDiagnostics = eventData.FrameworkDiagnosticResult; s.Stack = eventData.Stack; s.Timestamp = datetime; plugin.FailedTestData = [plugin.FailedTestData; struct2table(s)]; end end end
创建测试类
在您的工作文件夹中,创建包含以下测试类的文件 ExampleTest.m
。
classdef ExampleTest < matlab.unittest.TestCase methods(Test) function testOne(testCase) testCase.assertGreaterThan(5,10) end function testTwo(testCase) wrongAnswer = 'wrong'; testCase.verifyEmpty(wrongAnswer,'Not Empty') testCase.verifyClass(wrongAnswer,'double','Not double') end function testThree(testCase) testCase.assertEqual(7*2,13,'Values not equal') end function testFour(testCase) testCase.fatalAssertEqual(3+2,6); end end end
testFour
中的致命断言失败会导致框架停止运行并引发错误。在此示例中,没有后续测试。如果有后续测试,框架将不会运行该测试。
将插件添加到测试运行程序并运行测试
在命令提示符处,基于 ExampleTest
类创建测试套件,并创建测试运行程序。
import matlab.unittest.TestSuite import matlab.unittest.TestRunner suite = TestSuite.fromClass(?ExampleTest); runner = TestRunner.withNoPlugins;
创建一个 myPlugin
实例并将其添加到测试运行程序。运行测试。
p = DiagnosticRecorderPlugin; runner.addPlugin(p) result = runner.run(suite);
Error using ExampleTest/testFour (line 16)
Fatal assertion failed.
对于失败的致命断言,框架会引发错误,并且测试运行程序不会返回 TestResult
对象。但是,DiagnosticRecorderPlugin
会存储关于该测试及之前测试的信息以及失败断言。
检查诊断信息
在命令提示符下查看关于失败测试的信息。该信息保存在插件的 FailedTestData
属性中。
T = p.FailedTestData
T = 5×6 table Name Type TestDiagnostics FrameworkDiagnostics Stack Timestamp _______________________ _________________ ______________________________ ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ ____________ ____________________ 'ExampleTest/testOne' 'Assertion' 'TestDiagnostics not provided' 'assertGreaterThan failed.↵--> The value must be greater than the minimum value.↵↵Actual Value:↵ 5↵Minimum Value (Exclusive):↵ 10' [1x1 struct] 17-Jul-2017 12:41:18 'ExampleTest/testTwo' 'Verification' 'Not Empty' 'verifyEmpty failed.↵--> The value must be empty.↵--> The value has a size of [1 5].↵↵Actual char:↵ wrong' [1x1 struct] 17-Jul-2017 12:41:18 'ExampleTest/testTwo' 'Verification' 'Not double' 'verifyClass failed.↵--> The value's class is incorrect.↵ ↵ Actual Class:↵ char↵ Expected Class:↵ double↵↵Actual char:↵ wrong' [1x1 struct] 17-Jul-2017 12:41:18 'ExampleTest/testThree' 'Assertion' 'Values not equal' 'assertEqual failed.↵--> The values are not equal using "isequaln".↵--> Failure table:↵ Actual Expected Error RelativeError ↵ ______ ________ _____ __________________↵ ↵ 14 13 1 0.0769230769230769↵↵Actual Value:↵ 14↵Expected Value:↵ 13' [1x1 struct] 17-Jul-2017 12:41:18 'ExampleTest/testFour' 'Fatal Assertion' 'TestDiagnostics not provided' 'fatalAssertEqual failed.↵--> The values are not equal using "isequaln".↵--> Failure table:↵ Actual Expected Error RelativeError ↵ ______ ________ _____ __________________↵ ↵ 5 6 -1 -0.166666666666667↵↵Actual Value:↵ 5↵Expected Value:↵ 6' [1x1 struct] 17-Jul-2017 12:41:18
有很多选项可用于对这些信息进行存档或后处理。例如,您可以将变量保存为 MAT 文件或使用 writetable
将该表写出为各种文件类型,例如 .txt
、.csv
或 .xls
。
查看第三项测试失败的堆栈信息
T.Stack(3)
ans = struct with fields: file: 'C:\Work\ExampleTest.m' name: 'ExampleTest.testTwo' line: 9
显示框架针对第五项测试失败显示的诊断信息。
celldisp(T.FrameworkDiagnostics(5))
ans{1} = fatalAssertEqual failed. --> The values are not equal using "isequaln". --> Failure table: Actual Expected Error RelativeError ______ ________ _____ __________________ 5 6 -1 -0.166666666666667 Actual Value: 5 Expected Value: 6
另请参阅
matlab.unittest.plugins.TestRunnerPlugin
| matlab.unittest.TestCase
| matlab.unittest.TestRunner
| addlistener