В этом примере показано, как написать тест, который использует среду тестирования приложений и платформу для мокинга. Приложение содержит диалоговое окно выбора файла и метку, указывающую на выбранный файл. Чтобы протестировать приложение программно, используйте объект mock, чтобы задать поведение селектора файлов.
Создайте 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;
Создайте 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 __________
Чтобы протестировать приложение без ручного вмешательства, используйте платформу для мокинга. Измените приложение, чтобы принять службу выбора файлов вместо ее реализации в приложении (dependency injection).
Создайте 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 __________
matlab.mock.TestCase
| matlab.uitest.TestCase