Testing UI5/Fiori Applications – qUnit
Getting Started with testing SAPUI5/Fiori Applications
qUnits are written to test the functionality.
For UI5/Fiori applications, mainly we write qUnits for formatter.js,controller.js etc files in this context.
Step1: Once a SAPUI5/Fiori Application is developed. Now add a test folder to the project structure as below.
Create a subfolder “unit” to write the test cases .
Step2: Now I want start with formatter file to include qUnits. create a folder “model” and add new file “formatter.js”
sap.ui.require(
[
“com/sap/<project-name>/util/Formatter”, // add the file path for which qUnit’s you are intending to write.
“sap/ui/model/resource/ResourceModel”,
“sap/ui/thirdparty/sinon”,
“sap/ui/thirdparty/sinon-qunit”
],
function (formatter, ResourceModel) {
“use strict”;
}
);
Before adding test cases to formatter.js. lets create “unitTests.qunit.html” file to run and display test results.
Step3:
Create a new “unitTests.qunit.html” file to run the Unit tests.
<!DOCTYPE html>
<html>
<head>
<title>Unit tests for “Application Name”</title>
<meta http-equiv=’X-UA-Compatible’ content=’IE=edge’>
<meta charset=”utf-8″>
<script id=”sap-ui-bootstrap”
src=”/resources/sap-ui-core.js”
data-sap-ui-resourceroots='{
“com.sap.edaas”: “../../”,
“test.unit”: “./”
}’>
</script>
<script>
jQuery.sap.require(“sap.ui.qunit.qunit-css”);
jQuery.sap.require(“sap.ui.thirdparty.qunit”);
jQuery.sap.require(“sap.ui.qunit.qunit-junit”);
jQuery.sap.require(“sap.ui.qunit.qunit-coverage”);
// model tests
jQuery.sap.require(“test.unit.model.formatter”);
</script>
</head>
<body>
<div id=”content”></div>
<h1 id=”qunit-header”>Unit tests for “Application Name”</h1>
<h2 id=”qunit-banner”></h2>
<h2 id=”qunit-userAgent”></h2>
<div id=”qunit-testrunner-toolbar”></div>
<ol id=”qunit-tests”></ol>
<div id=”qunit-fixture”></div>
</body>
</html>
Step 4:
In your project, if you have defined a Formatter function as below
sap.ui.define([], function () {
“use strict”;
return {
statusText: function (sStatus) {
var resourceBundle = this.getView().getModel(“i18n”).getResourceBundle();
switch (sStatus) {
case “A”:
return resourceBundle.getText(“invoiceStatusA”);
case “B”:
return resourceBundle.getText(“invoiceStatusB”);
case “C”:
return resourceBundle.getText(“invoiceStatusC”);
default:
return sStatus;
}
}
};
});
webapp/i18n/i18.properties file
invoiceStatusA=New
invoiceStatusB=In Progress
invoiceStatusC=Done
Then you would have to write test cases in step2 as below
sap.ui.require(
[
“sap/ui/demo/wt/model/formatter”,
“sap/ui/model/resource/ResourceModel”,
“sap/ui/thirdparty/sinon”,
“sap/ui/thirdparty/sinon-qunit”
],
function (formatter, ResourceModel) {
“use strict”;
QUnit.module(“Formatting functions”, {
setup: function () {
this._oResourceModel = new ResourceModel({
bundleUrl : jQuery.sap.getModulePath(“sap.ui.demo.wt”, “/i18n/i18n.properties”)
});
},
teardown: function () {
this._oResourceModel.destroy();
}
});
QUnit.test(“Should return the translated texts”, function (assert) {
// Arrange
var oViewStub = {
getModel: this.stub().withArgs(“i18n”).returns(this._oResourceModel)
};
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”);
});
}
);
Step 5:
Similarly, i’m now adding test cases for another module “Number Unit”. each function within formatter can be termed as module.
sap.ui.require(
[
“sap/ui/demo/bulletinboard/model/formatter”,
“sap/ui/thirdparty/sinon”,
“sap/ui/thirdparty/sinon-qunit”
],
function (formatter) {
“use strict”;
QUnit.module(“Number unit”);
function numberUnitValueTestCase(assert, sValue, fExpectedNumber) {
// Act
var fNumber = formatter.numberUnit(sValue);
// Assert
assert.strictEqual(fNumber, fExpectedNumber, “The rounding was correct”);
}
QUnit.test(“Should round down a 3 digit number”, function (assert) {
numberUnitValueTestCase.call(this, assert, “3.123”, “3.12”);
});
QUnit.test(“Should round up a 3 digit number”, function (assert) {
numberUnitValueTestCase.call(this, assert, “3.128”, “3.13”);
});
QUnit.test(“Should round a negative number”, function (assert) {
numberUnitValueTestCase.call(this, assert, “-3”, “-3.00”);
});
QUnit.test(“Should round an empty string”, function (assert) {
numberUnitValueTestCase.call(this, assert, “”, “”);
});
QUnit.test(“Should round a zero”, function (assert) {
numberUnitValueTestCase.call(this, assert, “0”, “0.00”);
});
QUnit.module(“Price State”);
function priceStateTestCase(oOptions) {
// Act
var sState = formatter.priceState(oOptions.price);
// Assert
oOptions.assert.strictEqual(sState, oOptions.expected, “The price state was correct”);
}
QUnit.test(“Should format the products with a price lower than 50 to Success”, function (assert) {
priceStateTestCase.call(this, {
assert: assert,
price: 42,
expected: “Success”
});
});
QUnit.test(“Should format the products with a price of 50 to Normal”, function (assert) {
priceStateTestCase.call(this, {
assert: assert,
price: 50,
expected: “None”
});
});
QUnit.test(“Should format the products with a price between 50 and 250 to Normal”, function (assert) {
priceStateTestCase.call(this, {
assert: assert,
price: 112,
expected: “None”
});
});
QUnit.test(“Should format the products with a price between 250 and 2000 to Warning”, function (assert) {
priceStateTestCase.call(this, {
assert: assert,
price: 798,
expected: “Warning”
});
});
QUnit.test(“Should format the products with a price higher than 2000 to Error”, function (assert) {
priceStateTestCase.call(this, {
assert: assert,
price: 2001,
expected: “Error”
});
});
}
);
Step 6: Now run the UnitTests.qunit.html file . Right click and select Run as Unit Test in WebIDE.
Successfully qUnits are now executed.