アプリ テスト フレームワークとモッキング フレームワークを使用するテストの記述
この例では、アプリ テスト フレームワークとモッキング フレームワークを使用するテストの記述方法を示します。アプリには、ファイル選択のダイアログ ボックスと、選択したファイルを示すラベルが含まれています。アプリをプログラムによりテストするには、モック オブジェクトを使用してファイル セレクターの動作を定義します。
アプリの作成
現在のフォルダー内に launchApp
アプリを作成します。ユーザーはこのアプリを使って入力ファイルを選択し、そのファイルの名前をアプリに表示できます。ファイル選択のダイアログ ボックスは、ユーザー入力を待機するブロッキング モーダル ダイアログ ボックスです。
function app = launchApp f = uifigure; button = uibutton(f,"Text","Input file"); button.ButtonPushedFcn = @(src,event) 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 app app.UIFigure = f; app.Button = button; app.Label = label; function file = pickFile [file,~,status] = uigetfile("*.*"); if status label.Text = file; end end end
テスト前にアプリのプロパティを調べるには、コマンド プロンプトで関数 launchApp
を呼び出します。この手順はテストには必要ありませんが、アプリ テストで使用されるプロパティを確認しておくと役に立ちます。たとえば、アプリ内の [Input file] ボタンにアクセスするには、app.Button
を使用します。
app = launchApp; app.Button
ans = Button (Input file) with properties: Text: 'Input file' Icon: '' ButtonPushedFcn: @(src,event)pickFile Position: [100 100 100 22] Show all properties
手動操作を伴うアプリのテスト
モックを使用しないで LaunchAppTest
テスト クラスを作成します。このテストでは、input.txt
ファイルが現在のフォルダー内に存在しなければなりません。これが存在しない場合は作成してください。テストでは、[Input file] ボタンをプログラムによりクリックして、ラベルが 'input.txt'
に一致することを検証します。手動でファイルを選択しなければなりません。
classdef LaunchAppTest < matlab.uitest.TestCase properties Filename = 'input.txt' end methods(TestClassSetup) function checkFile(testCase) import matlab.unittest.constraints.IsFile testCase.assertThat(testCase.Filename,IsFile) end end methods (Test) function testInput(testCase) app = launchApp; testCase.addTeardown(@close,app.UIFigure) testCase.press(app.Button) testCase.verifyEqual(app.Label.Text,testCase.Filename) end end end
テストを実行します。ファイル選択のダイアログ ボックスが表示されたら、input.txt
を選択して MATLAB がテストを続行できるようにします。それ以外のファイルを選択した場合はテストが失敗します。
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
ファイルの選択に関数 uigetfile
を使用する、既定の FileChooser
サービスを作成します。
classdef DefaultFileChooser < FileChooser methods function [file,folder,status] = chooseFile(~,varargin) [file,folder,status] = uigetfile(varargin{:}); end end end
オプションの FileChooser
オブジェクトを受け入れるようにアプリを変更します。入力なしで呼び出された場合、アプリは DefaultFileChooser
のインスタンスを使用します。
function app = launchApp(fileChooser) arguments fileChooser (1,1) FileChooser = DefaultFileChooser end f = uifigure; button = uibutton(f,"Text","Input file"); button.ButtonPushedFcn = @(src,event) 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 app app.UIFigure = f; app.Button = button; app.Label = label; function file = pickFile(fileChooser) [file,~,status] = fileChooser.chooseFile("*.*"); if status label.Text = file; end end end
LaunchAppTest
に次の変更を加えます。
matlab.uitest.TestCase
とmatlab.mock.TestCase
の両方から継承するようにクラスを変更します。properties
ブロックとTestClassSetup
methods
ブロックを削除します。モックがchooseFile
メソッド呼び出しの出力を定義するので、テストは外部ファイルの存在に依存しません。次のアクションを実行するように
testInput
メソッドを変更します。FileChooser
からモック オブジェクトを作成する。chooseFile
メソッドが入力"*.*"
で呼び出された場合の出力が、ファイル名 ('input.txt'
)、現在のフォルダー、および選択されたフィルター インデックス1
になるように、モック動作を定義する。これらの出力は、関数uigetfile
からの出力と類似しています。mockChooser
オブジェクトを使用してアプリを起動する。ボタンを押して選択されたファイルの名前を検証する。これらのアクションは元のテストと同じですが、モックによって出力値が割り当てられるので、テストを続行するためにアプリを手動で操作する必要はありません。
[Cancel] ボタンをテストするには、次のアクションを実行する
testCancel
という名前のTest
メソッドを追加します。FileChooser
からモック オブジェクトを作成する。chooseFile
メソッドが入力"*.*"
で呼び出された場合の出力が、ファイル名 ('input.txt'
)、現在のフォルダー、および選択されたフィルター インデックス0
になるように、モック動作を定義する。これらの出力は、ユーザーがファイルを選択してからキャンセルを選択した場合の関数uigetfile
からの出力と類似しています。mockChooser
オブジェクトを使用してアプリを起動する。ボタンをクリックし、テストが
chooseFile
メソッドを呼び出すこと、およびファイルが選択されなかったことをラベルが示すことを検証する。
classdef LaunchAppTest < matlab.uitest.TestCase & matlab.mock.TestCase methods (Test) function testInput(testCase) import matlab.mock.actions.AssignOutputs filename = 'input.txt'; [mockChooser,behavior] = testCase.createMock(?FileChooser); when(behavior.chooseFile("*.*"),AssignOutputs(filename,pwd,1)) app = launchApp(mockChooser); testCase.addTeardown(@close,app.UIFigure) testCase.press(app.Button) testCase.verifyEqual(app.Label.Text,filename) end function testCancel(testCase) import matlab.mock.actions.AssignOutputs [mockChooser,behavior] = testCase.createMock(?FileChooser); when(behavior.chooseFile("*.*"),AssignOutputs('input.txt',pwd,0)) app = launchApp(mockChooser); testCase.addTeardown(@close,app.UIFigure) testCase.press(app.Button) testCase.verifyCalled(behavior.chooseFile("*.*")) testCase.verifyEqual(app.Label.Text,'No file selected') end end end
テストを実行します。テストは、ファイルの手動選択なしで最後まで実行されます。
runtests("LaunchAppTest");
Running LaunchAppTest .. Done LaunchAppTest __________