Mit den End2End-Tests sollte, meiner Meinung nach, sofort begonnen werden, sobald man die erste Seite gebaut hat. Wie der Name schon sagt wird das Zusammenspiel der Komponenten und die Anbindung an Schnittstellen getestet. Dabei geht man davon aus, dass man die Implementierung nicht kennt. Für alle die mit dem Begriff nichts anfangen können, erkläre ich es: Man steuert die Anwendung über den Browser (programmatisch) und zwar genau so wie ein Nutzer sie bedienen würde. Dazu nutzt man verschiedenen Frameworks, die Schnittstellen zum Browser bereitstellen. Das bekannteste Framework hierfür ist Selenium. Die Programmiersprache ist mittlerweile egal. Es gibt für alle großen Sprachen eine Implementierung. Mein Gedanke beim Thema Full-Stack-Entwickler ist, dass ich gerne alle Bereiche (Frontend, Backend, QA) in derselben Sprache schreiben möchte. Was gibt es hierzu im Bereich Javascript/Typescript. In den letzten Jahren hat sich da wirklich viel getan. Die Browserhersteller haben eingesehen, dass es einen Bedarf an Headless-Browsern ( Browser ohne Benutzeroberfläche ) gibt. PhantomJS hat sehr viel dazu beigetragen (Möge es in Frieden ruhen :-) ). Ich habe mit eine zeit lang mit Puppeteer gearbeitet. Microsoft hat einige Entwickler aus diesem Projekt übernommen und seine Variante davon entwickelt: Playwright. Ich benutze gerne Software, die von großen Unternehmen betrieben wird, da sie genug Ressourcen aufbringen können, um es weiterzuentwickeln.
Playwright tut auch genau was es soll. Es hat eine einfache API, ist komplett mit Typescript kompatibel und einsteigerfreundlich. Ich zeige euch heute wie man es installiert und wie ein erster Test damit aussieht. Wie immer empfehle ich die hauseigene Dokumentation zu durchstöbern.
Genug Text, jetzt hauen wir in die Tasten.
Laut Dokumentation reicht ein install-Befehl. Wir legen erstmal einen neuen Ordner an und initialisieren ein node-Projekt und bestätigen und durch den Node-Projekt-Wizard:
mkdir E2E
cd E2E
npm init
Im Anschluss installieren wir Playwright:
npm i -D @playwright/test
// Browser installieren mit
npx playwright install
Jetzt müsste man über ein package.json-Skript oder direkt über npx starten können:
// in package.json ergänzen:
"scripts": {
"test:local": "PWDEBUG=console playwright test"
}
npm run test:local
// oder
npx playwright test
Bei mir auf der Konsole erschien direkt ein Fehler: Error: Cannot find module 'playwright'
Dieser Fehler lässt sich einfach weginstallieren:
npm install -D playwright
Jetzt sollte das Ausführen klappen und diese Meldung erscheinen:
=================
no tests found.
=================
Als nächstes legen wir die Konfigurationsdatei an.
touch playwright.config.ts
Wer keine Befehle mag, kann es gerne in der IDE per "neue Datei" anlegen versuchen.
Der Inhalt dieser Datei sieht bei mir so aus:
// playwright.config.ts
import { PlaywrightTestConfig, devices, expect } from "@playwright/test";
const config: PlaywrightTestConfig = {
forbidOnly: true,
retries: 3,
reporter: "line",
use: {
// Browser options
headless: true,
// Context options
viewport: { width: 1280, height: 1920 },
ignoreHTTPSErrors: true,
// Artifacts
screenshot: "only-on-failure",
video: "retry-with-video",
},
projects: [
{
name: "Chrome Stable",
use: {
browserName: "chromium",
// Test against Chrome Stable channel.
channel: "chrome",
launchOptions: {
slowMo: 300,
},
},
},
{
name: "Desktop Safari",
use: {
browserName: "webkit",
viewport: { width: 1200, height: 750 },
},
},
// Test against mobile viewports.
{
name: "Mobile Chrome",
use: devices["Pixel 5"],
},
{
name: "Mobile Safari",
use: devices["iPhone 12"],
},
{
name: "Desktop Firefox",
use: {
browserName: "firefox",
viewport: { width: 800, height: 600 },
},
},
],
};
export default config;
Jeder sollte unbedingt in die Doku schauen. Dort sind die meisten Flags erklärt. Ich gehe aber auch auf meine Auswahl ein:
Welche Browser man unterstützt möchte ist sehr unterschiedlich. Es gibt kein Richtig oder Falsch. Das muss projektindividuell entschieden werden.
Playwright sucht beim Start automatisch nach der Datei playwright.config.ts. Man kann die Datei benennen wie man möchte. Dies muss man Playwright aber über einen Kommandozeilenparameter mitteilen:
npx playwright test --config=meine.neue.konfigurationsdatei.ts
// oder in der package.json
...
scripts: {
"test:alternative": "playwright test --config=meine.neue.konfigurationsdatei.ts",
}
...
Ich fasse zusammen. Es ist alles installiert und konfiguriert. Wir legen jetzt mit dem Testen los.
Wir legen unter /src/specs eine Datei an. Das machen wir wir analog zu Jest. Die Testdateien enden auf .spec.ts und sehen vom Aufbau auch genauso aus.
import { test, expect } from "@playwright/test";
// besser in einer env variable aufgehoben
const TEST_URL = "http://localhost:3333";
test.describe("Lucky Path Test", () => {
test.beforeEach(async ({ page }) => {
await page.goto(TEST_URL);
});
test("should check the first page", async ({ page }) => {
const locator = page.locator("h1");
await expect(locator).toContainText("Kuba-Home");
});
});
Man findet sich schnell zurecht. Es ist das Describe-Skelett und das Test-Skelett vorhanden. Der Aufbau ist auch wieder derselbe. Man hat einen Initialisierungsteil, einen Zustandherbeiführungsteil und einen Erwartungsteil. Unterschied zu Jest ist, dass die Describe Methode aus dem "test"-Objekt kommt. Gleichermaßen ist es mit dem "beforeEach". Die Tests bekommen als Parameter ein page-Objekt injiziert. Mit diesem haben wir Zugriff auf die Webseite. Wir müssen dem Test sagen, wohin er im Browser navigieren soll. Als Default wird auf einer leeren Webseite gestartet. Vor jedem Test soll er in unserer Applikation starten. Die URL ist hart kodiert. Dies sollte, wie der Kommentar sagt, in eine Environment-Variable ausgelagert werden, damit man die Applikation auf verschiedenen Umgebungen testen kann und diese Parameter von außen einlesen kann. Der eigentliche Test startet nun auf der Seite der Applikation. In Zeile 12 sehen wir einen Locator. Das ist ein HTML-Knoten, der selektiert wird über CSS-Selektoren. Für den ersten einfachen Test suche ich auf der Seite die Überschrift. Den Locator übergebe ich dem expect-Block und erwarte, dass Kuba-Home im Titel steht. Wenn wir nun den Test ausführen, passiert nichts außer, dass in der Konsole das hier erscheint:
Using config at /home/jacob/stenciljs-tutorial/E2E/playwright.config.ts
Running 1 test using 1 worker
1 passed (2s)
Wollen wir etwas mehr Effekte, können wir den Debug-Modus anschmeißen:
"test:local": "PWDEBUG=console playwright test"
Der Parameter PWDEBUG=console öffnet den Browser und man bekommt etwas mehr Output in der Konsole.
Das war unser erster Test.
Im nächsten Artikel testen wir die Adressbuch-Applikation über Playwright durch.
Vielen Dank an Huluvu424242 für das Feedback und das Beheben meiner Vertipper!
Der Code hierzu liegt auf Github.
Ihr habt Fragen oder Anregungen? Schreibt mir bei Twitter.
Tausend Dank fürs Lesen!
Kuba