Skip to content

Latest commit

 

History

History
173 lines (114 loc) · 7.58 KB

README.md

File metadata and controls

173 lines (114 loc) · 7.58 KB

Step 27: Unit Test with QUnit

Now that we have a test folder in the app, we can start to increase our test coverage.

Actually, every feature that we added to the app so far, would require a separate test case. We have totally neglected this so far, so let’s add a simple unit test for our custom formatter function from Step 23. We will test if the long text for our status is correct by comparing it with the texts from our resource bundle.

📝 Note:

In this tutorial, we focus on a simple use case for the test implementation. If you want to learn more about QUnit tests, have a look at the Testing Tutorial tutorial, especially Step 2: A First Unit Test.

 


Preview

A unit test for our formatters is now available

You can access the live preview by clicking on this link: 🔗 Live Preview of Step 27.

To download the solution for this step as a zip file, just choose the link here: 📥 Download Solution for Step 27.


Coding

We add a new folder unit under the test folder and a model subfolder where we will place our formatter unit test. The folder structure matches the app structure to easily find the corresponding unit tests.

Folder Structure for this Step


webapp/test/unit/model/formatter.ts (New)

We create a new formatter.ts file under webapp/test/unit/model where the unit test for the custom formatter is implemented. The formatter function that we want to test is from the formatter.ts file located in the webapp/model folder.

The new formatter file just contains one QUnit module for our formatter function and one unit test for the formatter function. In the implementation of the statusText function that we created in Step 23, we use the translated texts when calling the formatter. As we do not want to test the SAPUI5 binding functionality, we just use text in the test instead of a ResourceBundle.

Finally, we perform our assertions. We check each branch of the formatter logic by invoking the isolated formatter function with the values that we expect in the data model (A, B, C, and everything else). We strictly compare the result of the formatter function with the hard-coded strings that we expect from the resource bundle and give a meaningful error message if the test should fail.

import ResourceModel from "sap/ui/model/resource/ResourceModel";
import Controller from "sap/ui/core/mvc/Controller";
import formatter from "../../../model/formatter";

QUnit.module("Formatting function", {});

QUnit.test("Should return the translated texts", (assert) => {
    const resourceModel = new ResourceModel({
        bundleUrl: sap.ui.require.toUrl("ui5/walkthrough/i18n/i18n.properties"),
        supportedLocales: [
            ""
        ],
        fallbackLocale: ""
    });

    const controllerMock = <Controller> <any> {
        getOwnerComponent() {
            return {
                getModel() {
                    return resourceModel;
                }
            };
        }
    };

    // System under test
    const fnIsolatedFormatter = formatter.statusText.bind(controllerMock);

    // 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");
});

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

We create a new unitTests.qunit.ts file under webapp/test/unit/. This script loads and executes our formatter.

QUnit.config.autostart = false;

// import all your QUnit tests here
void Promise.all([
	import("ui5/walkthrough/test/unit/model/formatter")
]).then(() => {
	QUnit.start();
});

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

Finally we create a new unitTests.qunit.html page under webapp/test/unit.

Since we are now in the webapp/test/unit folder, we actually need to go up two levels to get the webapp folder again. This namespace can be used inside the tests to load and trigger application functionality.

First, we load some basic QUnit functionality via script tags. Other QUnit tests can be added here as well. Then the HTML page loads our unitTests.qunit.ts script.

<!DOCTYPE html>
<html>
<head>
	<title>UI5 TypeScript Walkthrough - Unit Tests</title>
	<meta charset="utf-8">

	<script
		id="sap-ui-bootstrap"
		src="../../resources/sap-ui-core.js"
		data-sap-ui-resourceroots='{
			"ui5.walkthrough": "../../"
		}'
		data-sap-ui-async="true"
        data-sap-ui-oninit="module:ui5/walkthrough/test/unit/unitTests.qunit">
	</script>

	<link rel="stylesheet" type="text/css" href="../../resources/sap/ui/thirdparty/qunit-2.css">

	<script src="../../resources/sap/ui/thirdparty/qunit-2.js"></script>
	<script src="../../resources/sap/ui/qunit/qunit-junit.js"></script>

</head>
<body>
	<div id="qunit"/>
	<div id="qunit-fixture"/>
</body>
</html>

The so-called QUnit test suite is an HTML page that triggers all QUnit tests for the application. Most of it is generating the layout of the result page that you can see in the preview and we won’t further explain these parts.

If we now open the webapp/test/unit/unitTests.qunit.html file in the browser, we should see our test running and verifying the formatter logic.


Conventions

  • All unit tests are placed in the webapp/test/unit folder of the app.

  • Files in the test suite end with *.qunit.html.

  • The unitTests.qunit.html file triggers all unit tests of the app.

  • A unit test should be written for formatters, controller logic, and other individual functionality.

  • All dependencies are replaced by stubs to test only the functionality in scope.

 


Next: Step 28: Integration Test with OPA

Previous: Step 26: Mock Server Configuration


Related Information

Unit Testing with QUnit

QUnit Home Page

Testing Tutorial