© Gorodenkoff/Shutterstock.com
Teil 4: Tests für besondere Anwendungsfälle

Spezielle Testszenarien


In den vorherigen Artikeln haben wir uns entlang der im ersten Teil vorgestellten Testpyramide hochgearbeitet. Hierbei haben wir uns im zweiten Teil zunächst mit der Basis beschäftigt, genauer gesagt mit den Unit-Tests. Im dritten Teil widmeten wir uns den Integrations- und E2E-Tests und deckten damit insgesamt 80 bis 90 Prozent der typischen Testfälle ab. In diesem Teil werden wir nun Testszenarien betrachten, die spezielle Anforderungen behandeln.

Webanwendungen laufen heute in den unterschiedlichsten Umgebungen, etwa auf Smartphones, Desktoprechnern und Tablets. Hinzu kommt, dass die Browser in den Umgebungen in diversen Versionen vorkommen können, was sich wiederum auf vorhandene Browser-APIs oder das CSS-Layouting auswirken kann. Erschwerend kommt hinzu, dass diese Versionen auch parallel eingesetzt werden. Das liegt daran, dass nicht alle Rechner von ihren Anwendern gleichermaßen mit Updates versorgt werden oder aufgrund alter Betriebssystemversionen nicht versorgt werden können – beispielsweise dann, wenn es für das iOS- oder Android-Device keine Updates mehr gibt. Um sicherstellen zu können, dass die Anwendung auf allen Zielplattformen läuft, sollten die Anwendungen auf den entsprechenden Geräten mit den jeweiligen Browsern getestet werden.

Zum Entwickeln einer Webanwendung wird in der Regel ein Desktoprechner verwendet. Der typische Nutzer greift allerdings meist auf mobile Endgeräte zurück. Um sicherzustellen, dass die App sowohl auf Desktoprechnern als auch auf mobilen Endgeräten korrekt läuft und dargestellt wird, bietet es sich an, das Verhalten moderner Webanwendungen auf beiden Plattformen zu testen. Dabei sollte ein besonderes Augenmerk auf die Unterschiede zwischen mobilen Devices und Desktopgeräten gelegt werden. Das beginnt bereits beim Design einer Anwendung: Da Schaltflächen wie Buttons auf mobilen Geräten per Touch gesteuert werden, müssen sie ausreichend groß dimensioniert sein. Aber auch bei den funktionalen Anforderungen, die an Anwendungen gestellt werden, gibt es Unterschiede: Während etwa Menüs auf Desktopbrowsern vollständig angezeigt werden können, müssen sie auf mobilen Geräten beispielsweise zusammengeklappt oder in ein dynamisch öffnendes Pop-over ausgelagert werden. Neben der geringeren Displaygröße spielt aber auch die Leistungsfähigkeit eine Rolle: Mobile Geräte haben in der Regel eine geringere Rechenleistung und weniger RAM/Cache als Desktoprechner. Außerdem müssen sie für den mobilen Einsatz den Akku schonen, um eine lange Akkulaufzeit garantieren zu können, und sollen nur eine geringe Abwärme produzieren. Im mobilen Einsatz kommt hinzu, dass die Internetverbindung stark eingeschränkt oder nicht vorhanden sein kann. Diese oft vernachlässigten Szenarien sollten bei Entwicklung und Test ebenfalls berücksichtigt werden.

Auf der anderen Seite gilt es, unterschiedliche Browserfunktionalitäten zu berücksichtigen: Auf Smartphones übliche Features wie Kamera, Telefonzugriff oder Geolocation sind längst nicht auf allen Desktoprechnern vorhanden oder sinnvoll nutzbar.

Dieser Artikel liefert einen Überblick über verschiedene Hilfsmittel und Anbieter, um die genannten Herausforderungen mit Hilfe von Tests einzugrenzen und abzusichern. Dabei ist anzumerken, dass – obwohl ein Großteil der Anforderungen sicherlich hauptsächlich im Umfeld moderner Browser-SPA-Anwendungen relevant ist – die genannten Hilfsmittel im Prinzip auch auf klassische Java-MVC-Anwendungen zu übertragen sind.

HTML5 APIs

Moderne Browser bieten eine Menge APIs, die von einer Webanwendung angebunden werden können. Dazu gehören zum Beispiel Geolocation API oder Battery API, aber auch Standard-APIs wie Zugriff auf Datum und Uhrzeit. Auch sie sollten beim Testen der Anwendung berücksichtigt werden, sofern sie in der Anwendung zum Einsatz kommen. Rein funktionale Validierungen können dabei am besten auf der Ebene von Unit-Tests implementiert werden. Wenn ein Gesamtsystem im Rahmen von Ende-zu-Ende Tests jedoch möglichst nah an der echten Umgebung betrachtet werden soll, stellt sich die Frage, wie man mit externen Inputs und Interaktionen umgehen kann. Um im Test reproduzierbare Ergebnisse liefern zu können, ist es sinnvoll, bestimmte Umgebungszustände zu emulieren. Als Testszenario könnte man sich eine Anwendungsfunktion vorstellen, die innerhalb eines geografisch abgegrenzten Bereichs (Geofence) eine Nachricht anzeigen soll. Um die Geolocation des Geräts im Test stabil anzugeben, kann das native Browser-API mit einem Fake beziehungsweise (je nach Testframework) einem Stub belegt werden.

Falls Protractor als Test-Runner verwendet wird, zum Beispiel zusammen mit Jasmine und Selenium, muss man einen Fake als externes Skript hinzufügen. Solch ein Skript muss mit Protractor immer als String angegeben werden, wie in Listing 1 dargestellt. Im Beispiel wird dieser Fake im beforeEach-Callback, also vor jedem Test, hinzugefügt. Falls statt Protractor ein reiner Selenium-Test – zum Beispiel für klassische Webanwendungen – verwendet wird, kann man dieses Beispiel im Prinzip direkt übertragen.

Listing 1: Protractor-­Geolocation-Fake

beforeEach(() => { browser.executeScript(''+ 'window.navigator.geolocation.getCurrentPosition = '+ ' function(success, error){ '+ ' const position = { '+ ' "coords" : { '+ ' "latitude": "19.21095899", '+ ' "longitude": "52.31412314" '+ ' } '+ ' }; '+ ' success(position); '+ ' }' ) });

Mit Cypress ist dasselbe Szenario etwas direkter zu implementieren. Wird mittels cy.visit() eine Webseite geöffnet, so kann auch ein Konfigurationsobjekt übergeben werden. Dieses Objekt kann man nutzen, um beim Laden der Seite einen Cypress Stub auf die Geolocation zu legen (Listing 2).

Listing 2: Cypress Geolocation Stub

beforeEach(() => { cy.visit('http://localhost:4200', { onBeforeLoad: win => { cy.stub(win.navigator.geolocation, 'getCurrentPosition', (success, error) => { const position = { coords: { longitude: 52.31412314, latitude: 19.21095899 } }; success(position); }); } }); });

Mit Puppeteer als Testumgebung ist das Setzen einer Geolocation für Testzwecke direkt vorgesehen. Damit sich während des Tests nicht der Permission-Dialog für die Geolocation öffnet und so den Test blockiert, muss man zunächst die Permission für Geolocation überschreiben. Dann kann die Geolocation explizit gesetzt werden (Listing 3).

Listing 3: Überschreiben der Geolocation mit Puppeteer

await context.overridePermissions('https://example.com', [ 'geolocation' ]); const page = await context.newPage(); await page.setGeolocation({ Latitude: 19.21095899, longitude: 52.31412314 });

So wie die Geolocation in diesen beiden Beispielen für Testzwecke simuliert wurde, kann grundsätzlich auch mit anderen Browser-APIs verfahren werden.

Sollen bestimmte Browser-Events wie etwa ein Orientation Change getestet werden, so hängt die Unterstützung hier stark vom Test-Framework ab. Mit Cypress lassen sich zum Beispiel die Abmessungen und auch die Orientierung von Devices konfigurieren. Hier ist auch zu sehen, wie sich DOM-Events innerhalb des Tests auslösen lassen, wie etwa...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang