Запишите плагин, чтобы добавить данные в результаты испытаний

В этом примере показано, как создать плагин, который добавляет данные в TestResult объекты. Плагин добавляет фактические и ожидаемые значения в утверждении к Details свойство TestResult объект. Расширять TestRunner, плагин заменяет избранные методы matlab.unittest.plugins.TestRunnerPlugin класс.

Создайте сменный класс

В файле в вашей текущей папке создайте пользовательский сменный класс DetailsRecordingPlugin, который наследовался TestRunnerPlugin класс. Для полного кода для DetailsRecordingPlugin, см. Сводные данные Определения класса DetailsRecordingPlugin.

Сохранить фактические и ожидаемые значения в TestResult объекты, задайте два постоянных свойства, ActField и ExpField, в properties блок. Установите значение ActField к имени поля Details структура, которая содержит фактическое значение. Установите значение ExpField к имени поля, которое содержит ожидаемое значение.

properties (Constant,Access = private)
    ActField = 'ActualValue';
    ExpField = 'ExpectedValue';
end

Добавьте поля в свойство деталей

Добавить новые поля в Details свойство всего TestResult объекты, принадлежащие сеансу тестирования, замените runSession метод TestRunnerPlugin в methods блокируйтесь с protected доступ. runSession добавляют два пустых поля к Details структура TestResult объекты и вызывают метод суперкласса инициировать целый тестовый прогон.

methods (Access = protected)
    function runSession(plugin,pluginData)
        resultDetails = pluginData.ResultDetails;
        resultDetails.append(plugin.ActField,{})
        resultDetails.append(plugin.ExpField,{})
        runSession@matlab.unittest.plugins.TestRunnerPlugin(plugin,pluginData);
    end
end

Добавить поля, реализацию runSession содержит вызовы append метод matlab.unittest.plugins.plugindata.ResultDetails класс. Каждый вызов добавляет пустое поле в Details структура.

Расширение создания разделяемых испытательных стендов и экземпляров TestCase

Добавьте прослушиватели для AssertionPassed и AssertionFailed события путем расширения методов, используемых средой тестирования, чтобы создать содержание теста. Содержание теста включает TestCase экземпляры для каждого Test элемент, уровень класса TestCase экземпляры для TestClassSetup и TestClassTeardown блоки метода и Fixture экземпляры, используемые, когда TestCase класс имеет SharedTestFixtures атрибут.

Вызовите соответствующий метод суперкласса, когда вы замените методы создания. Прослушиватели, которые вы добавляете в возвращенный Fixture или TestCase экземпляры вызывают reactToAssertion вспомогательный метод выполниться каждый раз, когда утверждение выполняется. Чтобы добавить данные об утверждении в результаты испытаний, передайте экземпляр модификатора результата наряду с данными о прослушивателе события утверждения к вспомогательному методу.

Добавьте эти методы создания для methods блокируйтесь с protected доступ.

methods (Access = protected)
    function fixture = createSharedTestFixture(plugin, pluginData)
        fixture = createSharedTestFixture@...            
            matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData);
        resultDetails = pluginData.ResultDetails;
        fixture.addlistener('AssertionPassed',...
            @(~,evd)plugin.reactToAssertion(evd,resultDetails));
        fixture.addlistener('AssertionFailed',...
            @(~,evd)plugin.reactToAssertion(evd,resultDetails));
    end
        
    function testCase = createTestClassInstance(plugin,pluginData)
        testCase = createTestClassInstance@...
            matlab.unittest.plugins.TestRunnerPlugin(plugin,pluginData);
        resultDetails = pluginData.ResultDetails;
        testCase.addlistener('AssertionPassed',...
            @(~,evd)plugin.reactToAssertion(evd,resultDetails));
        testCase.addlistener('AssertionFailed',...
            @(~,evd)plugin.reactToAssertion(evd,resultDetails));
    end
        
    function testCase = createTestMethodInstance(plugin,pluginData)
        testCase = createTestMethodInstance@...
            matlab.unittest.plugins.TestRunnerPlugin(plugin,pluginData);
        resultDetails = pluginData.ResultDetails;
        testCase.addlistener('AssertionPassed',...
            @(~,evd)plugin.reactToAssertion(evd,resultDetails));
        testCase.addlistener('AssertionFailed',...
            @(~,evd)plugin.reactToAssertion(evd,resultDetails));
    end
end

Задайте вспомогательный метод

В methods блокируйтесь с private доступ, задайте вспомогательный метод reactToAssertion. Этот метод использует QualificationEventData экземпляр, чтобы извлечь фактические и ожидаемые значения в утверждениях на основе IsEqualTo ограничение, преобразует извлеченные значения в массивы ячеек и добавляет массивы ячеек к полям соответствующего TestResult объект.

methods (Access = private)
    function reactToAssertion(plugin,evd,resultDetails)
        if ~isa(evd.Constraint,'matlab.unittest.constraints.IsEqualTo')
            return
        end
        resultDetails.append(plugin.ActField,{evd.ActualValue})
        resultDetails.append(plugin.ExpField,{evd.Constraint.Expected})
    end
end

Сводные данные определения класса DetailsRecordingPlugin

Этот код предоставляет полное содержимое DetailsRecordingPlugin.

classdef DetailsRecordingPlugin < matlab.unittest.plugins.TestRunnerPlugin
    properties (Constant, Access = private)
        ActField = 'ActualValue';
        ExpField = 'ExpectedValue';
    end
    
    methods (Access = protected)
        function runSession(plugin,pluginData)
            resultDetails = pluginData.ResultDetails;
            resultDetails.append(plugin.ActField,{})
            resultDetails.append(plugin.ExpField,{})
            runSession@matlab.unittest.plugins.TestRunnerPlugin(plugin,pluginData);
        end
        
        function fixture = createSharedTestFixture(plugin, pluginData)
            fixture = createSharedTestFixture@...
                matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData);
            resultDetails = pluginData.ResultDetails;
            fixture.addlistener('AssertionPassed',...
                @(~,evd)plugin.reactToAssertion(evd,resultDetails));
            fixture.addlistener('AssertionFailed',...
                @(~,evd)plugin.reactToAssertion(evd,resultDetails));
        end
        
        function testCase = createTestClassInstance(plugin,pluginData)
            testCase = createTestClassInstance@...
                matlab.unittest.plugins.TestRunnerPlugin(plugin,pluginData);
            resultDetails = pluginData.ResultDetails;
            testCase.addlistener('AssertionPassed',...
                @(~,evd)plugin.reactToAssertion(evd,resultDetails));
            testCase.addlistener('AssertionFailed',...
                @(~,evd)plugin.reactToAssertion(evd,resultDetails));
        end
        
        function testCase = createTestMethodInstance(plugin,pluginData)
            testCase = createTestMethodInstance@...
                matlab.unittest.plugins.TestRunnerPlugin(plugin,pluginData);
            resultDetails = pluginData.ResultDetails;
            testCase.addlistener('AssertionPassed',...
                @(~,evd)plugin.reactToAssertion(evd,resultDetails));
            testCase.addlistener('AssertionFailed',...
                @(~,evd)plugin.reactToAssertion(evd,resultDetails));
        end
    end
    
    methods (Access = private)
        function reactToAssertion(plugin,evd,resultDetails)
            if ~isa(evd.Constraint,'matlab.unittest.constraints.IsEqualTo')
                return
            end
            resultDetails.append(plugin.ActField,{evd.ActualValue})
            resultDetails.append(plugin.ExpField,{evd.Constraint.Expected})
        end
    end
end

Создание тестового класса в качестве примера

В вашей текущей папке создайте файл с именем ExampleTest.m содержа следующий параметрированный тестовый класс. Класс приводит к тестовому набору с 25 элементами, каждый соответствующий эксперименту выполнил использование различного seed для генератора случайных чисел. В каждом эксперименте среда тестирования создает 1 100 вектор из нормально распределенных случайных чисел и утверждает, что величина различия между фактическим и ожидала, что демонстрационные средние значения в 0,1.

classdef ExampleTest < matlab.unittest.TestCase
    properties
        SampleSize = 100;
    end

    properties (TestParameter) 
        seed = num2cell(randi(10^6,1,25));
    end
        
    methods(Test)
        function testMean(testCase,seed)
            import matlab.unittest.constraints.IsEqualTo
            import matlab.unittest.constraints.AbsoluteTolerance
            rng(seed)
            testCase.assertThat(mean(randn(1,testCase.SampleSize)),...
                IsEqualTo(0,'Within',AbsoluteTolerance(0.1)));
        end
    end
end

Добавление плагина к исполнителю тестов и запущенным тестам

В командной строке создайте тестовый набор из ExampleTest класс.

import matlab.unittest.TestSuite
import matlab.unittest.TestRunner

suite = TestSuite.fromClass(?ExampleTest);

Создайте TestRunner экземпляр без плагинов. Этот код создает тихого бегуна и дает вам контроль над установленными плагинами.

runner = TestRunner.withNoPlugins;

Добавьте DetailsRecordingPlugin бегуну и запущенный тесты.

runner.addPlugin(DetailsRecordingPlugin)
result = runner.run(suite)
result = 

  1×25 TestResult array with properties:

    Name
    Passed
    Failed
    Incomplete
    Duration
    Details

Totals:
   18 Passed, 7 Failed (rerun), 7 Incomplete.
   0.12529 seconds testing time.

Чтобы получить больше информации о поведении генерации случайных чисел, создайте массив структур из Details структуры результатов испытаний.

details = [result.Details]
details = 

  1×25 struct array with fields:

    ActualValue
    ExpectedValue

Создайте массив, содержащий различие между фактическими и ожидаемыми значениями в каждом тесте, и затем отобразите ошибочные значения в столбчатом графике. Эти семь панелей с длиной, больше, чем 0,1, соответствуют проваленным тестам.

errorInMean = cell2mat([details.ExpectedValue]) - cell2mat([details.ActualValue]);

bar(errorInMean)
xlabel('Experiment')
ylabel('Error')

Bar graph depicting error versus experiment

Смотрите также

| | | | | |

Похожие темы