exponenta event banner

Write Test, использующий тестирование приложений и макетные фреймворки

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

Создать приложение

Создать launchApp в текущей рабочей папке. Приложение позволяет пользователю выбрать входной файл и отображает имя файла в приложении. Диалоговое окно выбора файла является блокирующим модальным диалоговым окном, которое ожидает пользовательского ввода.

function app = launchApp
    f = uifigure;
    button = uibutton(f,'Text','Input file');
    button.ButtonPushedFcn = @(src,evt)pickFile;
    label = uilabel(f,'Text','No file selected');
    label.Position(1) = button.Position(1) + button.Position(3) + 25;
    label.Position(3) = 200;
    
    % Add components to an App struct for output
    app.UIFigure = f;
    app.Button = button;
    app.Label = label;
    
    function file = pickFile()
        [file,folder,status] = uigetfile('*.*');
        if status
            label.Text = file;
        end
    end
end

Чтобы просмотреть свойства этого приложения перед тестированием, создайте экземпляр приложения в командной строке. Этот шаг не является необходимым для тестов, но полезно изучить свойства, используемые тестами приложения. Например, использовать app.Button для доступа к кнопке Input file в объекте приложения.

app = launchApp;

App window displaying Input file button

Тестирование приложения с помощью ручного вмешательства

Создать LaunchAppTest класс без использования макетов. Тест предполагает наличие файла input2.txt существует в текущей рабочей папке. Если он не существует, создайте его. Тест программирует нажатие кнопки Input file и проверяет соответствие метки 'input2.txt'. Необходимо вручную выбрать файл.

classdef LaunchAppTest < matlab.uitest.TestCase
    properties
        TestFile = 'input2.txt';
    end
    methods(TestClassSetup)
        function checkTestFiles(tc)
            import matlab.unittest.constraints.IsFile
            tc.assumeThat(tc.TestFile,IsFile)
        end
    end
    methods (Test)
        function testInputButton(tc)
            app = launchApp;
            tc.addTeardown(@close,app.UIFigure);
            
            tc.press(app.Button);

            tc.verifyEqual(app.Label.Text,tc.TestFile)
        end
    end
end

Запустите тест. При появлении диалогового окна выбора файла выберите input2.txt позволяет MATLAB продолжить тест. Выбор любого другого файла приводит к сбою теста.

results = runtests('LaunchAppTest');
Running LaunchAppTest
.
Done LaunchAppTest
__________

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

Чтобы протестировать приложение без ручного вмешательства, используйте насмешливую структуру. Измените приложение, чтобы принять службу выбора файлов вместо ее реализации в приложении (инъекция зависимостей).

Создать FileChooser услуга с Abstract способ, реализующий функциональность выбора файла.

classdef FileChooser
    % Interface to choose a file
    methods (Abstract)
        [file,folder,status] = chooseFile(chooser,varargin)
    end
end

Создание значения по умолчанию FileChooser который использует uigetfile функция для выбора файла.

classdef DefaultFileChooser < FileChooser
    methods
        function [file,folder,status] = chooseFile(chooser,varargin)
            [file,folder,status] = uigetfile(varargin{:});
        end
    end
end

Измените приложение, чтобы принять необязательный FileChooser объект. При вызове без входных данных приложение использует экземпляр DefaultFileChooser.

function app = launchApp(fileChooser)
    if nargin==0
        fileChooser = DefaultFileChooser;
    end
    f = uifigure;
    button = uibutton(f,'Text','Input file');
    button.ButtonPushedFcn = @(src,evt)pickFile(fileChooser);
    label = uilabel(f,'Text','No file selected');
    label.Position(1) = button.Position(1) + button.Position(3) + 25;
    label.Position(3) = 200;
    
    % Add components to an App struct for output
    app.UIFigure = f;
    app.Button = button;
    app.Label = label;
    
    function file = pickFile(fileChooser)
        [file,folder,status] = fileChooser.chooseFile('*.*');
        if status
            label.Text = file;
        end
    end
end

Внести следующие изменения в LaunchAppTest.

  • Изменение теста на наследование от обоих matlab.uitest.TestCase и matlab.mock.TestCase.

  • Удалить properties блок и TestClassSetup блок. Поскольку макет определяет выходные данные chooseFile вызов метода, тест не основывается на существовании внешнего файла.

  • Изменить testInputButton метод испытания, чтобы он делал эти вещи.

    • Создание имитационного объекта FileChooser.

    • Определите имитационное поведение так, что, когда chooseFile метод вызывается с вводом '*.*', выходные данные - имя тестового файла ('input2.txt'), текущей рабочей папки и выбранного индекса фильтра, равного 1. Эти выходы аналогичны выходам из uigetfile функция.

    • Нажмите кнопку и проверьте выбранное имя файла. Эти шаги те же, что и в исходном тесте, но макет назначает выходные значения, поэтому вам не нужно взаимодействовать с приложением, чтобы продолжить тестирование.

  • Для проверки кнопки Cancel добавьте метод тестирования testInputButton_Cancel чтобы он делал эти вещи.

    • Создание имитационного объекта FileChooser.

    • Определите имитационное поведение так, что, когда chooseFile метод вызывается с вводом '*.*', выходные данные - имя тестового файла ('input2.txt'), текущей рабочей папки и выбранного индекса фильтра 0. Эти выходы аналогичны выходам из uigetfile если пользователь выбирает файл, а затем выбирает отмену.

    • Нажмите кнопку и убедитесь, что тест вызывает chooseFile и что метка указывает, что файл не был выбран.

classdef LaunchAppTest < matlab.uitest.TestCase & matlab.mock.TestCase
    methods (Test)
        function testInputButton(tc)
            import matlab.mock.actions.AssignOutputs
            fname = 'myFile.txt';
            
            [mockChooser,behavior] = tc.createMock(?FileChooser);
            when(behavior.chooseFile('*.*'),AssignOutputs(fname,pwd,1))
            
            app = launchApp(mockChooser);
            tc.addTeardown(@close,app.UIFigure);
            
            tc.press(app.Button);

            tc.verifyEqual(app.Label.Text,fname);
        end
        
        function testInputButton_Cancel(tc)
            import matlab.mock.actions.AssignOutputs
            
            [mockChooser, behavior] = tc.createMock(?FileChooser);
            when(behavior.chooseFile('*.*'),AssignOutputs('myFile.txt',pwd,0))
            
            app = launchApp(mockChooser);
            tc.addTeardown(@close,app.UIFigure);
            
            tc.press(app.Button);
            
            tc.verifyCalled(behavior.chooseFile('*.*'));
            tc.verifyEqual(app.Label.Text,'No file selected');
        end
    end
end

Запустите тесты. Тесты выполняются до завершения без выбора файла вручную.

results = runtests('LaunchAppTest');
Running LaunchAppTest
..
Done LaunchAppTest
__________

См. также

|

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