<!DOCTYPE html>
<html>
<head>
<title>OPA tests for Todo List</title>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta charset="utf-8">
<script id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-bindingSyntax="complex"
data-sap-ui-compatVersion="edge"
data-sap-ui-preload="async"
data-sap-ui-resourceRoots='{"sap.ui.demo.todo": "../../"}'>
</script>
<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-2-css.js"></script>
<script>
QUnit.config.autostart = false;
sap.ui.getCore().attachInit(function() {
sap.ui.require([
"sap/ui/demo/todo/test/integration/AllJourneys"
], function() {
QUnit.start();
});
});
</script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
AllJourneys.js
: the container file for all Test-Journeys.sap.ui.require([
"sap/ui/test/Opa5"
/* Pages */
/* Journeys */
], function (Opa5) {
Opa5.extendConfig({
autoWait: true
/* Default settings */
});
});
autoWait
in default config. This excludes checking inactive or non-interactable Controls, so turn it off in specific (see below) waitFor
s (e.g. in test senarios when Message toasts are involved that only disappear after n
number of seconds). But it will help in waiting for asynchronous operations on the UI to complete before test execution continues.├── AllJourneys.js
├── FilterJourney.js
├── SearchJourney.js
├── TodoListJourney.js
├── opaTests.qunit.html
└── pages
├── App.js
└── Common.js
Given
sets up the journey/test.When
gets the UI and environment into the state mandatory to test the business case.Then
performs the main assessment.opaTest("description", function (Given, When, Then) {
// Arrangements
Given.iStartTheApp();
// Actions
When.onTheAppPage.iEnterTextAndPressEnter("some text");
// Assertions
Then.onTheAppPage.iShouldSeeTheText("some text")
.and.iTeardownTheApp();
});
Given
-methods:iStartMyAppInAFrame
) or by launching the Component only (via iStartMyUIComponent
). The latter is significantly faster, easier to debug and also the “Fiori Launchpad way” of starting a UI5 app, but there’s advantages and disadvantages to both approaches. There's also a cool blog post on a custom launcher, simulating starting an app from the FLP à la "iStartMyUICompone....QUnit.module("GroupName")
:QUnit.module("Todo List");
opaTest(...);
opaTest(...);
opaTest(...);
QUnit.module("Footer");
opaTest(...);
opaTest(...);
sap.ui.require([
"sap/ui/test/Opa5"
], function (Opa5) {
"use strict";
Opa5.createPageObjects({
onTheAppPage: {
/* common methods outsourced in separate file "Common.js" */
baseClass: Common,
actions: {
iEnterTextForNewItemAndPressEnter: function (text) {
return this.waitFor({
/* */
});
}
},
assertions: {
iShouldSeeTheItemBeingAdded: function (iItemCount, sLastAddedText) {
return this.waitFor({
/* */
});
}
}
}
});
});
sap.ui.test.Opa5.waitFor()
- a method generating a Promise, used to synchronize application state with test state.OPA tests need to be synchronized with the application.
sap.ui.test.Opa5.waitFor()
is the code tool for that.
waitFor
. The documentation has a solid list of how to retrieve and operate Controls, so here’s only an excerpt for some cases:byId: function(sId) {
return this.waitFor({
id: sId,
viewName: "sap.ui.demo.todo.App",
success : function (oControl) {
/* assert sth on oControl */
}
})
}
withHelpOfMatchers: function (sText) {
return this.waitFor({
controlType: "sap.m.Button",
viewName: "sap.ui.demo.todo.App",
// require sap.ui.test.matchers.PropertyStrictEquals and
// use as PropertyStrictEquals
matchers: new PropertyStrictEquals({
name: "text",
value: sText
}),
success: function (oButton) {
/* assert sth on oButton */
}
})
}
controlType
:inPopup: function (sControlTypeInPopup, sText) {
return this.waitFor({
controlType: sControlTypeInPopup,
// require sap.ui.test.matchers.PropertyStrictEquals and
// use as PropertyStrictEquals
matchers: new PropertyStrictEquals({
name: "text",
value: sText
}),
searchOpenDialogs: true,
success: function (oButton) {
/* assert sth on oButton */
}
})
}
jQuery(oControl.getDomRef()).trigger()
, but use the OPA-native sap.ui.test.actions
instead. Again, the documentation has some good examples, so only note the basic code concept here:iEnterTextForSearchAndPressEnter: function (sId, sViewName, sText) {
return this.waitFor({
id: sId,
viewName: sViewName,
// require sap.ui.test.actions.EnterText and
// use as EnterText
actions: [new EnterText({text: sText})],
errorMessage: "The text cannot be entered"
});
}
sap.ui.test.Opa.config
of 15 seconds: they might have eventually already been passed in the test case throwing the error. So all following tests run into the default timeout.success
handler of a waitFor
, chances are that the application’s UI is off timing-wise and the interaction fails:// will fail occasionally!
this.waitFor({
id: "listItemId",
// dependening on the processing power of the computer executing the test,
// the list might not be entirely rendered and thus DOM operation on
// list item nodes not available yet
success: function (oListItem) {
// double-bad: jQuery instead of sap.ui.test.actions.Press
oListItem.$("bla").trigger("tap");
// ...
}
}
waitFor
's actions
to interact with UI5 controls, along with autoWait
:this.waitFor({
id: "listItemId",
actions: new Press() // require: sap.ui.test.actions.Press as "Press",
autoWait: true
}
// e.g. with a French system/browser, this will fail
matchers: [new PropertyStrictEquals({
name: "text",
value: iNumberItemsLeft + (iNumberItemsLeft === 1 ? " item left" : " items left")
})
I18NText
-matcher: it will retrieve the correct text from the appropriate i18n-model for the browser runtime environment.// ...
oItemLeftMatcher = new I18NText({
propertyName: "text",
key: "ITEM_LEFT"
}
// ...
// multi-lang match of label text
return this.waitFor({
id: sItemsLeftLabelIdText,
viewName: sViewName,
matchers: oItemLeftMatcher,
success: function () {
Opa5.assert.ok(true, "" + iNumberItemsLeft + " items left");
},
errorMessage: "Items are not selected."
});
waitFor
additionally adds test-application synchronization, it’s hard to debug between the journey steps (Given
-Arrangements, When
-Actions and Then
-Assertions).waitFor
to break into application runtime and test state:opaTest("again: should unselect an item", function (Given, When, Then) {
// Arrangements
Given.iStartTheApp();
//Actions
When.onTheAppPage.iEnterTextForNewItemAndPressEnter("my test")
.and.iSelectAllItems(true)
.and.iClearTheCompletedItems();
// debug the test and UI here!});
When.waitFor({
success: function() {
debugger;
}
});
When.onTheAppPage.iEnterTextForNewItemAndPressEnter("my test")
.and.iSelectTheLastItem(true)
.and.iSelectTheLastItem(false);
// Assertions
Then.onTheAppPage.iShouldSeeTheLastItemBeingCompleted(false).
and.iTeardownTheApp();
});
sap.ui.test.Opa5.waitFor()
is the programming means to sync test state and application state in order to avoid timing-based errors. Use its’ matchers
, checks
and actions
extensively to find and interact with UI5 controls.You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
8 | |
6 | |
5 | |
4 | |
4 | |
3 | |
3 | |
3 | |
3 | |
3 |