Oberflächentests mit Playwright
Ziel
Dieser Beitrag demonstriert den Einsatz von Playwright für automatisierte UI-Tests im Rahmen eines bestehenden SvelteKit-5-Projekts. Als Anwendungsfall dient ein interaktives Vier-Gewinnt-Spiel, das bereits in modularer Komponentenstruktur umgesetzt wurde. Im Fokus stehen die Teststrategie, die technische Umsetzung sowie bewährte Praktiken zur Testbarkeit.
Tech-Stack
-
Framework: SvelteKit 5 (mit SSR, runes, TypeScript)
-
Styling & UI: TailwindCSS, shadcn-svelte, Lucide Icons
-
Testing: Playwright (im e2e/-Verzeichnis)
Komponenten- und Logikstruktur
Das Spiel ist aufgeteilt in UI-Komponenten und eine von der Darstellung entkoppelte Spiel-Logik. Dies erleichtert das Testen, da Interaktionen klar über definierte Zustände und DOM-Selektoren nachvollziehbar sind.
Auszug der Komponentenstruktur:
|
Modul |
Funktion |
|---|---|
|
Board.svelte |
Steuert Spiellogik und UI-Rendering |
|
Cell.svelte |
Stellt einzelne Spielfelder dar |
|
StatusDisplay.svelte |
Zeigt aktuellen Spieler oder Gewinner an |
|
logic/game.ts |
Kapselt Board-Initialisierung, Zugverarbeitung, Siegprüfung |
|
ui/ |
Generische UI-Komponenten auf Basis von shadcn-svelte |
Testansatz mit Playwright
Playwright wird für klassische End-to-End-Tests genutzt. Ziel ist es, die wichtigsten Interaktions- und Zustandsänderungen der UI automatisiert zu prüfen. Die Tests befinden sich im Verzeichnis e2e/ und greifen über dedizierte data-test-Attribute auf UI-Elemente zu.
Beispiele getesteter Szenarien:
-
Initialzustand des Boards (alle Zellen leer)
-
Abwechselndes Setzen von Spielsteinen
-
Gewinnszenarien (z. B. vertikale Viererreihe)
-
Anzeige des Gewinners
Beispiel: Vertikaler Siegtest
test('ein Spieler gewinnt vertikal', async ({ page }) => {
for (let i = 0; i < 3; i++) {
await page.locator('[data-test=column-0]').click(); // red
await page.locator('[data-test=column-1]').click(); // yellow
}
await page.locator('[data-test=column-0]').click(); // red gewinnt
const winnerText = await page.locator('[data-test=winner]');
await expect(winnerText).toHaveText(/red/);
});
Weitere Tests überprüfen korrekte DOM-Zustände nach Klicks, das Wechseln des Spielers und die visuelle Darstellung des Ergebnisses.
Projektstruktur (Ausschnitt)
├── e2e/
│ └── game.spec.ts # Playwright-Tests
├── src/
│ ├── lib/
│ │ ├── components/
│ │ │ ├── game/ # Spiel-Komponenten
│ │ │ └── ui/ # Generische UI-Komponenten
│ │ └── logic/
│ │ └── game.ts # Spiellogik
│ └── routes/
│ └── +page.svelte # Einstiegspunkt der App
├── playwright.config.ts # Playwright-Konfiguration
Best Practices für UI-Tests
-
Stabile Selektoren: Durchgehende Verwendung von data-test-Attributen zur gezielten DOM-Auswahl
-
Testbare Architektur: Trennung von Spiellogik und Darstellung erhöht die Wiederverwendbarkeit und Testbarkeit
-
Vorhersehbare Zustände: Einsatz von beforeEach() zur Initialisierung des Spielzustands
-
Atomic Testing: Jeder Test prüft eine isolierte Funktionalität (Single Responsibility)
-
Lesbare Tests: Namen und Kommentare beschreiben das Verhalten, nicht die Implementierung
Weiterführende Ressourcen
Fazit
Durch die Integration von Playwright lassen sich komplexe UI-Interaktionen in SvelteKit-Anwendungen automatisiert und zuverlässig testen. Die klare Trennung von Logik und Oberfläche, kombiniert mit stabilen Selektoren, bildet die Grundlage für robuste und wartbare UI-Tests – sowohl in Lernkontexten als auch in produktionsnahen Szenarien.