Main Content

診断の詳細を保存するプラグインの作成

この例では、診断の詳細を保存するためのカスタム プラグインを作成する方法を説明します。このプラグインはテストの失敗をリッスンし、診断情報を保存して、フレームワークでテストを完了した後にアクセスできるようにします。

プラグインの作成

作業フォルダーのファイルで、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 などの様々なファイル形式で書き出したりできます。

3 番目のテスト エラーに関するスタック情報を表示します。

T.Stack(3)
ans = 

  struct with fields:

    file: 'C:\Work\ExampleTest.m'
    name: 'ExampleTest.testTwo'
    line: 9

5 番目のテスト エラーに関してフレームワークが示した診断結果を表示します。

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

参考

| | |

関連するトピック