Main Content

앱 테스트 프레임워크와 모의 프레임워크를 사용하는 테스트 작성하기

이 예제에서는 앱 테스트 프레임워크와 모의 프레임워크를 사용하는 테스트를 작성하는 방법을 보여줍니다. 앱에는 파일 선택 대화 상자와 선택한 파일을 나타내는 레이블이 포함됩니다. 앱을 프로그래밍 방식으로 테스트하려면 모의 객체를 사용하여 파일 선택기의 동작을 정의하십시오.

앱 만들기

현재 폴더에 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 함수를 호출하십시오. 이 단계는 테스트에 반드시 필요하진 않지만 앱 테스트에서 사용하는 속성을 살펴보는 것은 도움이 됩니다. 예를 들어, app.Button을 사용하여 앱 내 Input file 버튼에 액세스합니다.

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

App window displaying the Input file button and the text "No file selected"

수동 작업으로 앱 테스트하기

모의 객체를 사용하지 않고 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

테스트를 실행합니다. 파일 선택 대화 상자가 나타나면 MATLAB에서 테스트를 진행할 수 있도록 input.txt를 선택합니다. 다른 파일을 선택하면 테스트가 실패합니다.

runtests("LaunchAppTest");
Running LaunchAppTest
.
Done LaunchAppTest
__________

완전히 자동화된 테스트 생성하기

수동 작업 없이 앱을 테스트하려면 모의 프레임워크를 사용하십시오. 앱에서 파일 선택 서비스를 구현하는 대신 이 서비스를 허용하도록 앱을 수정합니다(의존성 주입).

파일 선택 기능을 구현하는 Abstract 메서드를 사용하여 FileChooser 서비스를 만듭니다.

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.TestCasematlab.mock.TestCase 모두로부터 상속되도록 변경합니다.

  • properties 블록과 TestClassSetup methods 블록을 제거합니다. 모의 객체가 chooseFile 메서드 호출의 출력값을 정의하기 때문에 테스트는 외부 파일 존재 여부에 좌우되지 않습니다.

  • 다음 작업을 수행하도록 testInput 메서드를 변경합니다.

    • FileChooser에서 모의 객체 생성.

    • "*.*" 입력값으로 chooseFile 메서드 호출 시, 출력값이 파일 이름('input.txt'), 현재 폴더 및 선택한 필터 인덱스 1이 되도록 모의 객체 동작 정의. 이 출력값은 uigetfile 함수의 출력값과 유사합니다.

    • mockChooser 객체를 사용하여 앱 실행.

    • 버튼을 누르고 선택한 파일 이름 확인. 이러한 동작은 원래 테스트와 동일하지만 모의 객체가 출력값을 할당하기 때문에 테스트 진행을 위해 사용자가 앱과 상호 작용할 필요가 없습니다.

  • Cancel 버튼을 테스트하기 위해 다음 작업을 수행하도록 testCancel이라는 이름의 Test 메서드를 추가합니다.

    • FileChooser에서 모의 객체 생성.

    • "*.*" 입력값으로 chooseFile 메서드 호출 시, 출력값이 파일 이름('input.txt'), 현재 폴더 및 선택한 필터 인덱스 0이 되도록 모의 객체 동작 정의. 사용자가 파일을 선택한 후 Cancel을 선택하면 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
__________

참고 항목

클래스

관련 항목