What OPA5 Is (and Isn't)
OPA5 is SAPUI5's framework for end-to-end tests. It drives your app in a real browser, clicks buttons, types text, and asserts what the user sees. It is not a unit test framework — that job belongs to QUnit.
OPA5 answers one question: does the app behave correctly from the user's point of view? If it runs in a browser, OPA5 can test it.
Project Setup
You need three files in a test/integration folder: an arrangement, a journey, and a page object. Plus an opaTests.qunit.html runner page. The standard layout:
opaTests.qunit.html— bootstraps OPA5 and lists your journeysjourneys/StartupAndNavigationJourney.js— the test scriptpages/AppPage.js— reusable actions and assertions
Generate the folder structure once and copy it into every new app. Consistency here saves more time than any testing trick.
Writing Your First Journey
A journey is a sequence of When (actions) and Then (assertions) steps. OPA5 waits for UI5 to finish rendering before each step, so you never write manual sleep timers.
opaTest("Should show the order list", function (Given, When, Then) {
Given.iStartMyApp();
When.onTheOrderList.iPressTheGoButton();
Then.onTheOrderList.theOrderTableShouldContainRows()
.and.iTeardownMyApp();
});
Notice how readable this is. Anyone on the team can look at the test name and the steps and understand the scenario being verified.
The Page Object Pattern
Actions and assertions live in page objects, not in journeys. Say you have a search button — the page object exposes iPressTheGoButton so every journey can reuse it.
actions: {
iPressTheGoButton: function () {
return this.waitFor({
id: "goButton",
actions: new Press()
});
}
},
assertions: {
theOrderTableShouldContainRows: function () {
return this.waitFor({
id: "orderTable",
matchers: new AggregationFilled({ name: "items" }),
success: function (oTable) {
Opa5.assert.ok(
oTable.getItems().length > 0,
"The table has items"
);
}
});
}
}
Always prefer stable control IDs over CSS selectors in waitFor. A renamed CSS class shouldn't break your tests.
Running and Debugging
Open opaTests.qunit.html in a browser and watch the tests run — OPA5 visually drives the app, so you can see exactly where a test fails. For CI, run the same page headless with Karma or UI5 Tooling's test task.
Flaky test? Nine times out of ten it is a timing issue: an extra waitFor with a proper matcher fixes it. Never add setTimeout workarounds.
Keep the Suite Healthy
Tag slow journeys so developers can run a fast subset locally and the full suite in CI. Delete tests that fail for reasons nobody understands — a red suite that everyone ignores is worse than a small suite everyone trusts.
One reliable journey is worth more than ten flaky ones. Grow the suite by adding tests for bugs you actually fixed, so regressions get caught where they hurt before.
Wrapping Up
Start with one happy-path journey: open the app, do the main action, assert the result. Grow from there. A small OPA5 suite that runs on every commit catches regressions before your users do.
Do you use OPA5, or are you still testing manually? Share your experience in the comments.