이제 App에 테스트 범위를 확대 하기 위해 formatter 함수에 대한 간단한 unit test를 추가한다.

Preview

28_preview.png

Coding

Walkthrough - Step 28.

webapp/test/unit/model/formatter.js

/*global QUnit*/

sap.ui.define([
    "sap/ui/demo/walkthrough/model/formatter",
    "sap/ui/model/resource/ResourceModel"
], function (formatter, ResourceModel) {
    "use strict";

    QUnit.module("Formatting functions", {
        beforeEach: function () {
            this._oResourceModel = new ResourceModel({
                bundleUrl: sap.ui.require.toUrl("sap/ui/demo/walkthrough") + "/i18n/i18n.properties"
            });
        },
        afterEach: function () {
            this._oResourceModel.destroy();
        }
    });


    QUnit.test("Should return the translated texts", function (assert) {

        // Arrange
        // this.stub() does not support chaining and always returns the right data
        // even if a wrong or empty parameter is passed.
        var oModel = this.stub();
        oModel.withArgs("i18n").returns(this._oResourceModel);
        var oViewStub = {
            getModel: oModel
        };
        var oControllerStub = {
            getView: this.stub().returns(oViewStub)
        };

        // System under test
        var fnIsolatedFormatter = formatter.statusText.bind(oControllerStub);

        // Assert
        assert.strictEqual(fnIsolatedFormatter("A"), "New", "The long text for status A is correct");

        assert.strictEqual(fnIsolatedFormatter("B"), "In Progress", "The long text for status B is correct");

        assert.strictEqual(fnIsolatedFormatter("C"), "Done", "The long text for status C is correct");

        assert.strictEqual(fnIsolatedFormatter("Foo"), "Foo", "The long text for status Foo is correct");
    });

});

테스트하려는 formatter 파일은 종속성으로 로드하고 번역된 텍스트가 정확한지 확인하기 위해 ResourceModel을 종속성으로 로드한다.
테스트를 위한 formatter 파일은 하나의 Qunit 모듈을 포함한다.
QUnit의 beforeEach 함수에서 i18n등의 localized된 Text를 ResourceBundle로 읽고 afterEach 함수에서 ResourceBundle을 소멸시킨다.
이 함수는 각 테스트가 실행되기 전후에 호출된다.

다음은 formatter 함수에 대한 unit test이다.
controller, view, model 기능은 테스트하고 싶지 않으므로 먼저 SinonJS 및 stub method를 사용한다.
단위 테스트를 할대 SinonJS는 모든 객체에 대해 this.stub ()를 사용하여 모의 테스트할 동작에 대해 새로운 스텁을 만든다.

이 function들은 stub의 동작을 변경하는 데 사용할 수 있는 method 말고 전체 SinonJS 테스트 API를 지원한다.
그런다음 JavaScript의 bind 함수를 호출하여 stub을 statusText formatter 바인딩한다.

이 pointer는 이제 변수(fnIsolatedFormatter)를 사용하여 함수가 호출 될 때 controller stub에 바인딩된다.

마지막으로 assertion을 수행한다. 우리는 데이터 모델에서 isolated formatter 함수를 호출하여 포맷터 논리의 각 분기를 확인한다.
포매터 함수의 결과를 리소스 번들에서 비교하고 테스트가 실패시 오류 메시지를 표시한다.
여기에 문자열을 리소스 번들 속성과 관련된 issue를 식별한다.
모델의 value가 누락 된 경우 번들에서 실제 값을 점검하면 테스트가 성공적으로 수행된다.

webapp/test/unit/unitTests.qunit.html (New)

<!DOCTYPE html>
<html>
<head>
    <title>Unit tests for SAPUI5 Walkthrough</title>
    <meta charset="utf-8">

    <script
        id="sap-ui-bootstrap"
        src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
        data-sap-ui-resourceroots='{
            "sap.ui.demo.walkthrough": "../../"
        }'
        data-sap-ui-async="true">
    </script>

    <link rel="stylesheet" type="text/css" href="https://openui5.hana.ondemand.com/resources/sap/ui/thirdparty/qunit-2.css">

    <script src="https://openui5.hana.ondemand.com/resources/sap/ui/thirdparty/qunit-2.js"></script>
    <script src="https://openui5.hana.ondemand.com/resources/sap/ui/qunit/qunit-junit.js"></script>
    <script src="https://openui5.hana.ondemand.com/resources/sap/ui/qunit/qunit-coverage.js"></script>
    <script src="https://openui5.hana.ondemand.com/resources/sap/ui/thirdparty/sinon.js"></script>
    <script src="https://openui5.hana.ondemand.com/resources/sap/ui/thirdparty/sinon-qunit.js"></script>

    <script src="unitTests.qunit.js"></script>
</head>
<body>
    <div id="qunit"/>
    <div id="qunit-fixture"/>
</body>
</html>

QUnit 테스트를 하기 위한 애플리케이션에 대한 모든 이벤트를 트리거하는 HTML 페이지이다.
미리보기에서 볼 수 있는 결과 페이지의 레이아웃을 생성한다. 이제 webapp/test/unit 폴더에 있기 때문에 네임스페이스 경로는 두 단계 위로 올라간다.

이 네임 스페이스는 테스트 내에서 응용 프로그램 기능을 로드하고 트리거한다.
기본 QUnit 기능을 로드 하기위해 스크립트를 넣어준다.
그런 다음 HTML 페이지에 unitTests.qunit.js라는 다른 스크립트를 로드하고 이 스크립트에서 포맷터를 실행한다.

webapp/test/unit/unitTests.qunit.js (New)

/* global QUnit */

QUnit.config.autostart = false;

sap.ui.getCore().attachInit(function () {
    "use strict";

    sap.ui.require([
        "sap/ui/demo/walkthrough/test/unit/model/formatter"
    ], function () {
        QUnit.start();
    });
});

해당 스크립트는 포맷터 파일을로드하고 실행한다.
webapp/test/unit/unitTests.qunit.html 파일을 브라우저에서 열면 테스트가 실행되고 포맷터 로직을 확인한다.

webapp/package.json

{
  "name": "WalkthroughTutorial",
  "private": true,
  "version": "1.0.0",
  "author": "SAP SE",
  "description": "UI5 Demo App - Walkthrough Tutorial",
  "scripts": {
    "serve": "ui5 serve --open /index.html",
    "test": "/test/unit/unitTests.qunit.html",
    "proxy": "node proxy.js"
  },
  "devDependencies": {
    "cors-anywhere": "^0.4.1"
  }
}

package.json의 scripts 부분에 test 명령어를 추가하여 npm run test를 통해 확인해보자

Conventions

  • 모든 unit test는 App의 webapp/test/unit 폴더에 있다.

  • test suite의 파일은 *.qunit.html로 끝난다.

  • unitTests.qunit.html 파일은 App의 모든 unit test를 실행한다.

  • 포맷터, 컨트롤러, 로직, 기타 개별 기능에 대한 단위 테스트를 작성해야한다.

  • 모든 종속성은 stub으로 대체되어 스코프 안에 기능만 테스트한다.

Unit Testing with QUnit

QUnit Home PageInformation published on non-SAP site

Sinon.JS Home PageInformation published on non-SAP site

Testing