Создание усовершенствованного пользовательского прибора

Этот пример показывает, как создать пользовательский прибор, который устанавливает переменную окружения. До тестирования этот фиксатор сохранит текущую переменную UserName.

Создание определения класса UserNameEnvironmentVariableFixture

В файле в вашей рабочей папке создайте новый класс, UserNameEnvironmentVariableFixture, который наследовался классу matlab.unittest.fixtures.Fixture. Поскольку вы хотите передать фиксатор имя пользователя, создайте свойство UserName передать данные между методами.

classdef UserNameEnvironmentVariableFixture < ...
        matlab.unittest.fixtures.Fixture
    
    properties (SetAccess=private)
        UserName
    end

Определение конструктора фиксатора

В блоке methods файла UserNameEnvironmentVariableFixture.m создайте метод конструктора, который подтверждает вход и задает SetupDescription. Сделайте, чтобы конструктор принял вектор символов и установил свойство UserName фиксатора.

    methods
        function fixture = UserNameEnvironmentVariableFixture(name)
            validateattributes(name, {'char'}, {'row'}, '','UserName')
            fixture.UserName = name;
            fixture.SetupDescription = sprintf( ...
                'Set the UserName environment variable to "%s".',...
                fixture.UserName);
        end

Реализация Метода настройки

Подклассы класса Fixture должны реализовать метод setup. Используйте этот метод, чтобы сохранить исходную переменную UserName. Этот метод также задает TeardownDescription и указывает задачу отключения установки UserName к исходному состоянию после тестирования.

Задайте метод setup в блоке methods файла UserNameEnvironmentVariableFixture.m.

        function setup(fixture)
            originalUserName = getenv('UserName');
            fixture.assertNotEmpty(originalUserName, ...
                'An existing UserName environment variable must be defined.')
            fixture.addTeardown(@setenv, 'UserName', originalUserName)
            fixture.TeardownDescription = sprintf(...
                'Restored the UserName environment variable to "%s".',...
                originalUserName);
            setenv('UserName', fixture.UserName)
        end
    end

Реализация isCompatible Метода

Классы, которые выводят от Fixture, должны реализовать метод isCompatible, если конструктор конфигурируем. Поскольку можно сконфигурировать свойство UserName через конструктора, UserNameEnvironmentVariableFixture должен реализовать isCompatible.

Метод isCompatible вызван двумя экземплярами того же класса. В этом случае это вызвано двумя экземплярами UserNameEnvironmentVariableFixture. Среда тестирования считает эти два экземпляра совместимыми, если их свойства UserName равны.

В новом блоке methods в UserNameEnvironmentVariableFixture.m задайте метод isCompatible, который возвращает логический 1 (true) или логический 0 (false).

    methods (Access=protected)
        function bool = isCompatible(fixture, other)
            bool = strcmp(fixture.UserName, other.UserName);
        end
    end

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

Ниже полное содержимое UserNameEnvironmentVariableFixture.m.

classdef UserNameEnvironmentVariableFixture < ...
        matlab.unittest.fixtures.Fixture
    
    properties (SetAccess=private)
        UserName
    end
    
    methods
        function fixture = UserNameEnvironmentVariableFixture(name)
            validateattributes(name, {'char'}, {'row'}, '','UserName')
            fixture.UserName = name;
            fixture.SetupDescription = sprintf( ...
                'Set the UserName environment variable to "%s".',...
                fixture.UserName);
        end
        
        function setup(fixture)
            originalUserName = getenv('UserName');
            fixture.assertNotEmpty(originalUserName, ...
                'An existing UserName environment variable must be defined.')
            fixture.addTeardown(@setenv, 'UserName', originalUserName)
            fixture.TeardownDescription = sprintf(...
                'Restored the UserName environment variable to "%s".',...
                originalUserName);
            setenv('UserName', fixture.UserName)
        end
    end
    
    methods (Access=protected)
        function bool = isCompatible(fixture, other)
            bool = strcmp(fixture.UserName, other.UserName);
        end
    end
end

Применение пользовательского прибора к единственному тестовому классу

В файле в вашей рабочей папке создайте следующий тестовый класс, ExampleTest.m.

classdef ExampleTest < matlab.unittest.TestCase
    methods(TestMethodSetup)
        function mySetup(testCase)
            testCase.applyFixture(...
                UserNameEnvironmentVariableFixture('David'));
        end
    end
    
    methods (Test)
        function t1(~)
            fprintf(1, 'Current UserName: "%s"', getenv('UserName'))
        end
    end
end

Этот тест использует UserNameEnvironmentVariableFixture для каждого теста в классе ExampleTest.

В командной строке, запущенной тест.

run(ExampleTest);
Running ExampleTest
Current UserName: "David".
Done ExampleTest
__________

Применение пользовательского прибора как разделяемого фиксатора

В вашей рабочей папке создайте три тестовых класса с помощью разделяемого фиксатора. Используя разделяемый фиксатор позволяет UserNameEnvironmentVariableFixture быть совместно использованным через классы.

Создайте testA.m можно следующим образом.

classdef (SharedTestFixtures={...
        UserNameEnvironmentVariableFixture('David')}) ...
        testA < matlab.unittest.TestCase
    methods (Test)
        function t1(~)
            fprintf(1, 'Current UserName: "%s"', getenv('UserName'))
        end
    end
end

Создайте testB.m можно следующим образом.

classdef (SharedTestFixtures={...
        UserNameEnvironmentVariableFixture('Andy')}) ...
        testB < matlab.unittest.TestCase
    methods (Test)
        function t1(~)
            fprintf(1, 'Current UserName: "%s"', getenv('UserName'))
        end
    end
end

Создайте testC.m можно следующим образом.

classdef (SharedTestFixtures={...
        UserNameEnvironmentVariableFixture('Andy')}) ...
        testC < matlab.unittest.TestCase
    methods (Test)
        function t1(~)
            fprintf(1, 'Current UserName: "%s"', getenv('UserName'))
        end
    end
end

В командной строке, запущенной тесты.

runtests({'testA','testB','testC'});
Setting up UserNameEnvironmentVariableFixture
Done setting up UserNameEnvironmentVariableFixture: Set the UserName environment variable to "David".
__________

Running testA
Current UserName: "David".
Done testA
__________

Tearing down UserNameEnvironmentVariableFixture
Done tearing down UserNameEnvironmentVariableFixture: Restored the UserName environment variable to "Kim".
__________

Setting up UserNameEnvironmentVariableFixture
Done setting up UserNameEnvironmentVariableFixture: Set the UserName environment variable to "Andy".
__________

Running testB
Current UserName: "Andy".
Done testB
__________

Running testC
Current UserName: "Andy".
Done testC
__________

Tearing down UserNameEnvironmentVariableFixture
Done tearing down UserNameEnvironmentVariableFixture: Restored the UserName environment variable to "Kim".
__________

Вспомните, что фиксаторы совместимы, если их свойства UserName соответствуют. Тесты в testA и testB используют несовместимые разделяемые фиксаторы, поскольку 'David' не равен 'Andy'. Поэтому среда вызывает фиксатор teardown и методы setup между вызовами testA и testB. Однако разделяемый испытательный стенд в testC совместим с фиксатором в testB, таким образом, среда не повторяет отключение фиксатора и настройку перед testC.

Альтернативный Подход к Вызову addTeardown в Методе настройки

Альтернативный подход к использованию метода addTeardown в рамках метода setup должен реализовать отдельный метод teardown. Вместо метода setup, описанного выше, реализуйте следующий setup и методы teardown в UserNameEnvironmentVariableFixture.m.

 Чередуйте определение класса UserNameEnvironmentVariableFixture

Метод setup не содержит вызов addTeardown или определения для TeardownDescription. Эти задачи понижены к методу teardown. Альтернативное определение класса содержит дополнительное свойство, OriginalUser, который позволяет информации быть переданной между методами.

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

Похожие темы