exponenta event banner

Записать подключаемый модуль для добавления данных в результаты тестирования

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

Создать класс подключаемого модуля

В файле текущей папки создайте класс пользовательского подключаемого модуля DetailsRecordingPlugin, которая наследует от TestRunnerPlugin класс. Полный код для 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 структура.

Расширение возможностей создания общих тестовых приборов и экземпляров, связанных с,

Добавить прослушиватели для 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 access, определите метод помощника 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.

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 элементами, каждый из которых соответствует эксперименту, выполненному с использованием различных начальных чисел для генератора случайных чисел. В каждом эксперименте структура тестирования создает вектор 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

Добавление подключаемого модуля в Test Runner и выполнение тестов

В командной строке создайте набор тестов из 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

См. также

| | | | | |

Связанные темы