Main Content

编写用于保存诊断详细信息的插件

本示例演示如何创建自定义插件来保存诊断详细信息。该插件将侦听测试失败并保存诊断信息,以便您在框架完成测试后访问此信息。

创建插件

在工作文件夹下的文件中,创建从 matlab.unittest.plugins.TestRunnerPlugin 类继承的 myPlugin 类。在插件类中:

  • 定义插件的 FailedTestData 属性,用于存储来自失败测试的信息。

  • 覆盖 TestRunnerPlugin 的默认 createTestMethodInstance 方法,以侦听断言、致命断言和验证失败,以及记录相关信息。

  • 覆盖 TestRunnerPlugin 的默认 runTestSuite 方法,以初始化 FailedTestData 属性值。如果您没有初始化该属性值,则在每次使用同一测试运行器运行测试时,失败测试信息都会附加到 FailedTestData 属性。

  • 定义辅助函数 recordData,以将关于测试失败的信息保存为表。

该插件保存 PluginDataQualificationEventData 对象中包含的信息。它还会保存失败类型和时间戳。

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

另请参阅

| | |

相关主题