编写使用 App 测试和模拟框架的测试
此示例说明如何编写使用 App 测试框架和模拟框架的测试。该 App 包含一个文件选择对话框和一个指示所选文件的标签。要以编程方式测试该 App,请使用一个 mock 对象来定义文件选择器的行为。
创建 App
在当前工作文件夹中创建 launchApp
App。该 App 允许用户选择一个输入文件并在 App 中显示文件的名称。文件选择对话框是一个等待用户输入的阻断型模态对话框。
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 的属性,请在命令提示符下创建该 App 的实例。此步骤对于测试不是必需的,但是了解 App 测试使用的属性会很有帮助。例如,使用 app.Button
访问 App 对象内的 Input file 按钮。
app = launchApp;
在手动干预下测试 App
在不使用 mock 的情况下创建 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 __________
创建全自动测试
要测试 App 而无需手动干预,请使用模拟框架。将 App 修改为接受文件选择服务,而不是在 App 中实现该服务(依赖项注入)。
使用 Abstract
方法创建一个 FileChooser
服务,用于实现文件选择功能。
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
将 App 更改为接受可选的 FileChooser
对象。当在没有输入的情况下调用时,该 App 使用 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
代码块。由于 mock 定义chooseFile
方法调用的相应输出,因此测试不依赖于外部文件的存在。更改
testInputButton
测试方法,以便它执行下列操作。创建
FileChooser
的一个 mock 对象。定义 mock 行为,以便在使用输入
'*.*'
调用chooseFile
方法时,输出为测试文件名 ('input2.txt'
)、当前工作文件夹和选定的筛选器索引 1。这些输出类似于uigetfile
函数的输出。按下按钮并验证所选文件名称。这些步骤与原始测试中的步骤相同,但 mock 会分配输出值,因此您无需与 App 交互即可继续测试。
要测试 Cancel 按钮,请添加测试方法
testInputButton_Cancel
,以便它执行下列操作。创建
FileChooser
的一个 mock 对象。定义 mock 行为,以便在使用输入
'*.*'
调用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