Browser-Tests mit Playwright
Bei modernen Single Page Apps wird ein großer Teil der Anwendungslogik im Browser des Anwenders ausgeführt - und genau hier gilt es durch stabilen Betrieb zu überzeugen!
Automatisierte End to End Tests (E2E) des Gesamtsystems im Browser sind daher ein wichtiger Baustein einer guten Teststrategie. In jüngeren Projekten setzen wir hier auf die Playwright-Library, um die Eingaben des Anwenders zu simulieren.
Der Markt bietet bereits einige bekannte und verbreitete Lösungen für diesen Anwendungsfall.
Selenium WebDriver etwa findet sich in sehr vielen E2E Tests, doch es ist dafür bekannt, dass man häufig manuelle Schleifen einfügen muss, um auf UI-Elemente zu warten. So lässt sich etwa ein verzögert erscheinender Button natürlich erst dann anklicken, wenn seine Einblend-Animation abgeschlossen ist. Selenium WebDriver läuft außerhalb des Browsers, weiß nichts über seine Event Queue und kann hier daher auch nicht selbstständig unterstützen.
Man endet als Softwareentwickler oft damit, dass man “auf Verdacht” an vielen Stellen feste Wartezeiten einführt und die Tests so nicht nur langsam werden, sondern auch instabil. Denn manchmal ist die optimistisch gewählte Wartezeit dann eben doch noch zu kurz.
Cypress als jüngeres System läuft innerhalb des Browsers und weiß um seine Event Queue. Die Tests fallen so erheblich kürzer und stabiler aus, denn um Warteschleifen muss man sich als Software-Entwickler nicht mehr selbst kümmern. Der Fokus liegt klar auf den Testschritten bzw. Assertions.
In cloud Systemen sind allerdings oftmals verschiedene Websites an einem Use Case beteiligt. Anwender melden sich etwa bei einem zentralen Identity Provider an und arbeiten dann an anderer Stelle weiter. Cypress eignet sich nicht für die Automatisierung von Abläufen über verschiedene Domänen hinweg - denn es läuft im Browser zusammen mit der Webanwendung, und wird dabei ebenso wie diese auch durch die Same Origin Policy eingeschränkt. Bei einem Domänenwechsel bricht der Test sofort ab.
Playwright kann als junges Open Source-Projekt die wesentlichen Nachteile der beiden Systeme ausmerzen. Es läuft zwar außerhalb des Browsers, hat aber Einblick in die Event Queue und kann so automatisch Wartezyklen ausführen. Eine Beschränkung durch die Same Origin Policy besteht nicht; es lassen sich also mehrere Websites auf einmal automatisieren.
Alle großen Browser-Engines, also Chromium, Firefox und WebKit, sind einsetzbar und lassen sich darüber hinaus auch sehr einfach zusammen mit Playwright installieren. Werden die Tests etwa in JavaScript entwickelt - wobei Python, Java oder .NET ebenso möglich sind - so ist die Installation bereits durch ein
npm install playwright
abgeschlossen und alle Browser-Engines sind für Tests verfügbar. Unter Linux kann es allenfalls passieren, dass Playwright zusätzliche Bibliotheken für den Betrieb von WebKit erfordert, was aber aus den Fehlermeldungen klar ersichtlich wird.
Es ist im Folgenden sehr einfach, einen neuen Browser für Tests zu starten, nebst des im Testumfeld wichtigen isolierten Kontexts sowie einem virtuellen Browsertab:
const playwright = require('playwright');
const browser = await playwright.chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
…
await browser.close();
Die Page-Objekte dienen der Interaktion mit der Website:
await page.goto('https://google.de');
await page.click('text=Ich stimme zu');
await page.type('input[name=q]', 'conventic GmbH Bonn');
await page.keyboard.press('Enter');
// Hier erfolgt ein Wechsel der Seite auf eine völlig andere Domain:
await page.click('text=Website');
// Und dennoch kann es weitergehen...
await page.click('text=Zustimmen');
…
Was auf den ersten Blick nur wie eine reine Automatisierung wirkt, kann auch schon als Test fungieren, denn die Page-Methoden schlagen mit Exceptions fehl, sollte z.B. das angeklickte Element nicht vorhanden oder nicht sichtbar sein. Natürlich besteht aber auch die Möglichkeit, explizite Assertions zu formulieren:
const content = await page.textContent('nav:first-child');
expect(content).toBe('home');
Playwright erlaubt auch automatisierte Up- und Downloads von Dateien, nimmt Screenshots oder Videos der Website auf oder verbindet sich mit der Entwicklerkonsole des Browsers.
Welchen Testrunner man letzten Endes mit Playwright einsetzt, bleibt einem selbst überlassen. Wir haben mit Jasmine gute Erfahrungen gemacht, aber erst vor Kurzem wurde auch ein offizieller Testrunner direkt in Playwright integriert. Wir sind gespannt und werden sicherlich in Zukunft noch aufgreifen, wie er sich in der Praxis schlägt. Eines sei schon verraten: Um die Screenshot- und Videoaufzeichnung im Fehlerfall kümmert er sich ganz nebenbei.