Playwright Tutorial: E2E Testing modern und effizient

End-to-End Tests prüfen Ihre Anwendung aus Nutzersicht. Mit Playwright von Microsoft haben Sie ein modernes, schnelles und zuverlässiges Tool für Cross-Browser-Testing. In diesem Tutorial zeige ich Ihnen, wie Sie Playwright einrichten und effektive E2E-Tests schreiben.

Warum Playwright?

Playwright hat sich als einer der führenden E2E-Testing-Frameworks etabliert. Im Vergleich zu Selenium oder Cypress bietet es einige entscheidende Vorteile:

  • Multi-Browser: Chromium, Firefox und WebKit in einem Framework
  • Auto-Waiting: Wartet automatisch auf Elemente, keine flaky Tests
  • Parallele Ausführung: Tests laufen standardmäßig parallel
  • Trace Viewer: Mächtige Debugging-Tools für fehlgeschlagene Tests
  • Codegen: Automatische Testgenerierung durch Aufzeichnung

Installation und Setup

Die Installation ist denkbar einfach. In einem bestehenden Projekt führen Sie folgenden Befehl aus:

npm init playwright@latest

Der Installer fragt nach einigen Optionen und erstellt automatisch die Konfigurationsdatei playwright.config.ts sowie einen Beispieltest. Die Browser werden beim ersten Testlauf heruntergeladen.

playwright.config.ts – Wichtige Einstellungen:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  timeout: 30000,
  retries: 2,
  use: {
    baseURL: 'http://localhost:3000',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
  },
  projects: [
    { name: 'chromium', use: { browserName: 'chromium' } },
    { name: 'firefox', use: { browserName: 'firefox' } },
    { name: 'webkit', use: { browserName: 'webkit' } },
  ],
});

Den ersten Test schreiben

Playwright-Tests folgen einer intuitiven Syntax. Hier ein einfaches Beispiel für einen Login-Test:

import { test, expect } from '@playwright/test';

test('erfolgreicher Login', async ({ page }) => {
  // Zur Login-Seite navigieren
  await page.goto('/login');

  // Formular ausfüllen
  await page.getByLabel('E-Mail').fill('user@example.com');
  await page.getByLabel('Passwort').fill('geheim123');

  // Absenden
  await page.getByRole('button', { name: 'Anmelden' }).click();

  // Erwartung prüfen
  await expect(page).toHaveURL('/dashboard');
  await expect(page.getByText('Willkommen')).toBeVisible();
});

Locators: Elemente richtig finden

Die Wahl der richtigen Locators ist entscheidend für stabile Tests. Playwright bietet verschiedene Strategien, die nach Zuverlässigkeit geordnet sind:

LocatorBeispielEmpfehlung
getByRolepage.getByRole('button', { name: 'Senden' })Beste Wahl, barrierefrei
getByLabelpage.getByLabel('E-Mail')Ideal für Formularfelder
getByTextpage.getByText('Willkommen')Für sichtbaren Text
getByTestIdpage.getByTestId('submit-btn')Wenn andere nicht funktionieren
CSS/XPathpage.locator('.btn-primary')Nur als letzter Ausweg

Praxis-Tipp: Bevorzugen Sie immer getByRole und getByLabel. Diese Locators orientieren sich an der Accessibility und sind robust gegenüber Design-Änderungen.

Page Object Model (POM)

Das Page Object Model ist ein Design Pattern, das Ihre Tests wartbar macht. Anstatt Locators direkt in Tests zu verwenden, kapseln Sie sie in Klassen:

// pages/LoginPage.ts
import { Page, Locator } from '@playwright/test';

export class LoginPage {
  readonly page: Page;
  readonly emailInput: Locator;
  readonly passwordInput: Locator;
  readonly submitButton: Locator;

  constructor(page: Page) {
    this.page = page;
    this.emailInput = page.getByLabel('E-Mail');
    this.passwordInput = page.getByLabel('Passwort');
    this.submitButton = page.getByRole('button', { name: 'Anmelden' });
  }

  async goto() {
    await this.page.goto('/login');
  }

  async login(email: string, password: string) {
    await this.emailInput.fill(email);
    await this.passwordInput.fill(password);
    await this.submitButton.click();
  }
}

Im Test verwenden Sie dann die Page-Klasse:

import { test, expect } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';

test('erfolgreicher Login', async ({ page }) => {
  const loginPage = new LoginPage(page);

  await loginPage.goto();
  await loginPage.login('user@example.com', 'geheim123');

  await expect(page).toHaveURL('/dashboard');
});

Debugging mit Playwright

Playwright bietet hervorragende Debugging-Werkzeuge:

UI Mode

Der UI Mode zeigt Tests visuell und ermöglicht Schritt-für-Schritt-Debugging:

npx playwright test --ui

Trace Viewer

Bei fehlgeschlagenen Tests zeichnet Playwright einen Trace auf. Damit sehen Sie Screenshots, Netzwerk-Requests und DOM-Snapshots für jeden Schritt:

npx playwright show-trace trace.zip

Codegen

Mit Codegen zeichnen Sie Aktionen auf und Playwright generiert den Testcode:

npx playwright codegen localhost:3000

CI/CD-Integration

Playwright integriert sich nahtlos in CI/CD-Pipelines. Hier ein Beispiel für GitHub Actions:

name: Playwright Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/

Fazit

Playwright macht E2E-Testing zuverlässig und effizient. Mit Auto-Waiting, dem Page Object Model und mächtigem Debugging schreiben Sie Tests, die stabil laufen und leicht zu warten sind. Starten Sie mit wenigen kritischen User Flows und erweitern Sie Ihre Test-Suite schrittweise.

E2E-Tests für Ihre Anwendung?