top of page
Geometric Abstract Shapes_edited.jpg
  • Patrick Fetscher

OPA5 Testing

Dieser Blog soll einen Überblick bieten, wie Code mit OPA5 getestet werden kann.


Was ist OPA5?

OPA ist die Abkürzung für One Page Acceptance und OPA5 ist ein Framework, welches auf Qunit und JavaScript basiert und ein Bestandteil des SAPUI5 Frameworks ist. Mit OPA5 können Benutzerinteraktionen, die Navigation innerhalb einer App und das Databinding der einzelnen Seitenelementen getestet werden.

Da JavaScript-Methoden grundsätzlich asynchron ausgeführt werden, und dies bei Interaktionstests in der Regel nicht zum gewünschten Ergebnis führt, wird bei OPA5 das sogenannte Polling verwendet. Das bedeutet, dass bei einem Funktionsaufruf nicht auf die Antwort gewartet wird, sondern das in einem definierten Zeitrahmen, dem Polling Intervall, der Status des Controls immer wieder abgefragt wird. Wird beispielsweise der Polling Intervall auf 200ms gesetzt, prüft die Anwendung alle 200ms ob bspw. alle Tabelleneinträge vorhanden sind oder nicht. Dieser Vorgang wird so lange wiederholt, bis die Aussage entweder zutrifft oder die sogenannte Timeout-Zeit überschritten ist und somit der Test fehlschlägt.


Aufbau Von OPA5 Tests

Wie oben zu sehen bilden die Journeys die Grundstruktur der OPA5 Tests. Deren Aufbau ist immer gleich:


AllJourneys.js

sap.ui.define([
    "sap/ui/test/Opa5",
    "./arrangements.Arrangement",
    "./NavigationJourney",
    "./EditJourney"
], function (Opa5, Arrangement) {
    "use strict";

    Opa5.extendConfig({
        arrangements: new Arrangement(),
        viewNamespace: "com.pure.wdi5testing.",
        autoWait: true
    });
});


Im sap.ui.define Block werden die zu verwendenden Ressourcen definiert (benötigte Module, Journeys die durchlaufen werden sollen). Im extendConfig Block werden die grundlegenden OPA5 Einstellungen definiert, also wo die Grundfunktionen abgelegt sind (Arrangements), in welchem Namespace die App läuft und ob die autoWait Funktionalität verwendet werden soll (schliesst bspw. die Überprüfung von inaktiver Elemente wie Messagetoasts aus).


OPA Journeys

sap.ui.define([
    "sap/ui/core/Configuration",
    "sap/ui/test/opaQunit",
    "./pages/Main"
], function (Configuration, opaTest, Main) {
    "use strict";

    opaTest("sprechende Beschreibung was der Testcase tun soll", 
function (Given, When, Then) {
        // Arrangements
        Given.iStartMyApp();

        //Action
        When.onMain.iDoSomething("some Properties");

        // Assertions
        Then.onMain.iShouldSeeSomething();
    });
});


In den Journeys wird die eigentliche Testabfolge definiert. Dazu werden vor allem die Seitenelemente verwendet (onMain). Ein Test hat immer den gleichen Aufbau. Es wird ein sprechender Text definiert, der beschreibt was der Test genau erreichen soll:

  • Im Given Block wird Ausgangszustand definiert (wird eigentlich nur zum Startup der Testumgebung gebraucht).

  • Im When Block werden alle Aktionen, die auf der Applikation ausgeführt werden sollen, definiert. Dies sind die Userinteraktionen die eintreten können, wie bspw. Texteingaben oder das Drücken eines Buttons.

  • Im Then Block sind die sogenannten Erwartungen definiert. Er beschreibt wie die Applikation nach den Aktionen aussehen soll, also bspw. wie viele Listeneinträge die Tabelle nach der Filterung noch darstellen soll.

OPA Page Objects

sap.ui.define([
    "sap/ui/test/Opa5",
    "./pages/CommonPage"
], function (Opa5, CommonPage) {
    "use strict";
    Opa5.createPageObjects({
        //give a meaningful name for the test code
        onThe<Page Object>: {
            viewName: "<Page ID>",
            //Optional: a class extending Opa5, with utility functionality
            baseClass: CommonPage,
            actions: {
                //place all arrangements and actions here
                <iDoSomething>: function(){
                    //always return this or a waitFor to allow chaining
                    return this.waitFor({
                    //see documentation for possibilities
                    });
                }
            },
            assertions: {
                //place all assertions here
                <iCheckSomething>: function () {
                    //always return this or a waitFor to allow chaining
                    return this.waitFor({
                        //see documentation for possibilities
                    });
                }
            }
        }
    });
});


In den Page-Objects Dateien werden, wie bereits erwähnt, die in den Journeys verwendeten Funktionen definiert. Für jede Seite, die getestet werden soll, bietet es sich an ein eigenes Page-Object zu erstellen. Für Methoden, die auf mehreren Seiten verwendet werden sollen, wie beispielsweise eine Texteingabe in einem Input Feld, kann das Common-Object verwendet werden. So muss die Methodik nur einmalig definiert werden und kann an mehreren Stellen wiederverwendet werden. Eingebunden werden diese Methoden über den define-Block (CommonPage).


Das zentrale Element der Page Objekte stellt die waitFor Sequenz. Damit wird sichergestellt, dass die Tests warten bis das gesuchte Element gefunden wurde und erst danach zum nächsten Schritt übergehen. Innerhalb der waitFor Funktion wird definiert, anhand welcher Eigenschaften das gesuchte Control identifiziert werden soll.

Die sicherste und performanteste Methode ist die Suche mit einer statischen ID in Verbindung mit dem ControlType. Stehen diese nicht zur Verfügung, gibt es aber auch die Möglichkeit andere Eigenschaften zu verwenden. Hierfür müssen aber sogenannte Matcher verwendet werden. Diese können entweder selbst definiert werden oder man verwendet einen vordefinierten Matcher aus dem Framework.


Ein vollständiger Auszug der mitgelieferten Matcher können unter


Ein paar Beispiele:


  • Es wird ein Titel gesucht, der über den gebundenen I18n Text identifiziert wird. Der Ausdruck searchOpenDialogs bestimmt, ob sich das gesuchte Element in einem Dialog befindet oder nicht:

  • Es wird ein List Item gesucht, welches über den BindingPath eindeutig identifiziert wird. Anschließend wird überprüft, ob das Item selektiert wurde. Trifft dies nicht zu wird die Error Message ausgegeben:

  • Es wird ein Button gesucht, welche über das Property Icon eindeutig identifiziert wird. Anschließend wird ein Press Event ausgelöst:

  • Es wird, wie im vorherigen Beispiel, ein Button mit Hilfe des Properties Icon gesucht. Zusätzlich wird überprüft ob das Element enabled ist. Nur wenn beide Eigenschaften zutreffen gibt die Methode ein positives Feedback.

Möchte man eine Liste von Controls erhalten, kann statt den Matchern ein Check verwendet werden. Dieser liefert beim Aufruf nicht nur ein einzelnes Control, sondern liefert als Übergabewert eine Liste von allen auf der Seite vorhandenen Controls, welche im Selektor definiert wurden.

Bei den Aktionen stellt sich ein ähnliches Bild wie bei den Matchern dar. Auch hier gibt es vom Framework vordefinierte Actions (Drag, Drop, EnterText, Press, Scroll) und es können Funktionen selbst definiert werden.


Bei den sogenannten Assertions reichen in aller Regel die vordefinierten Elemente. Mit ok (immer wahr), equal, propEqual, deepEqual, strictEqual und deren Negationen können in der Regel alle UseCases abgedeckt werden und es ist nicht mehr nötig eigene Validierungen zu erstellen, auch wenn dies gleich wie bei den vorhergehenden Bestandteilen ebenfalls möglich ist.


Darstellung nach und während der Testdurchführung


Tipps und Tricks bei Unit-Tests

  • Mock Daten

Beim Testen einer Applikation sollte versucht werden mit Mock Daten zu arbeiten. Somit kannst eine mögliche Fehlerquelle beim Testdurchlauf eliminiert werden. Daten im Backendsystem können sich jederzeit ändern und die Assertions fehlschlagen lassen. Die Mock Daten sollten in aller Regel stabil bleiben.


  • Debugging

OPA5 Test können gleich wie Applikationslogik selbst gedebuggt werden. Entweder wird im Coding das Schlüsselwort debugger  … function() { debugger } … gesetzt oder über die Entwicklertools (F12) einen Breakpoint. Das Framework selbst gibt die Möglichkeit die zurückgelieferten Ergebnisse zu untersuchen und etwaige Probleme zu identifizieren.

  • Karma

Der Karma Testrunner ist ein Tool, welches es ermöglicht, verschiedenste Tests in einer Vielzahl von Browsern auszuführen. Ein weiterer Vorteil ist, dass die Tests im sogenannten headless Mode ausgeführt werden können, sodass die Tests im Hintergrund zwar durchlaufen werden, aber sich keine Fenster öffnen und schließen und normal weitergearbeitet werden kann. Ein Reporting zu den durchgeführten Tests, wie beispielsweise Code-Coverage, kann mit Karma umgesetzt werden.

Aktuelle Beiträge

Alle ansehen

Basic Search als URL-Parameter

Bei der Navigation in SAP Fiori Applikationen können URL-Parameter an die SmartFilterBar übergeben werden. Dabei werden diese nach dem Semantischen Objekt angehägt, bspw. ?param=value. Da die Basic Se

bottom of page