End-to-End Testing

Playwright

Playwright ist ein Framework für cross-browser End-to-End-Tests mit Auto-Waiting, leistungsstarken Locators und Tooling für Tracing, Codegen und visuelle Vergleiche — alles in einem Paket.

intermediate14 min readUpdated 15. Sept. 2026
login.spec.ts
ts
// tests/login.spec.ts
import { test, expect } from "@playwright/test";

test("user can sign in", async ({ page }) => {
  await page.goto("/login");

  await page.getByLabel("Email").fill("[email protected]");
  await page.getByLabel("Password").fill("secret");
  await page.getByRole("button", { name: "Sign in" }).click();

  await expect(
    page.getByRole("heading", { name: "Dashboard" }),
  ).toBeVisible();
});
Gewartet von
Microsoft
Browser
Chromium, Firefox, WebKit
Locators
Role, label, text, test id
Warten
Automatisch
Tooling
Codegen, trace viewer, UI mode
Parallelität
Workers und Sharding

Warum es wichtig ist

Warum Playwright der moderne e2e-Standard ist

Eine API, drei Engines

Der gleiche Test läuft in Chromium, Firefox und WebKit, sodass du browser-spezifische Bugs findest, bevor es die Nutzer tun.

Auto-waiting

Locators warten, bis Elemente ausführbar sind, was fast alle willkürlichen Timeouts und Flakiness eliminiert.

Debugging-Tools

Codegen zeichnet Tests auf, der Trace Viewer spielt einen Durchlauf Frame für Frame ab und der UI mode macht das Debugging interaktiv.

Das Gesamtbild

Die drei Kernkonzepte hinter Playwright

Echte Browser, gesteuert durch Locators, automatisches Warten und erstklassiges Tooling für Debugging und Skalierung.

Locators

Finden

Elemente über Role, Label, Text und Test-ID abfragen, wobei das Warten in jede Aktion integriert ist.

Assertions

Verifizieren

Web-first Assertions, die so lange wiederholen, bis die Bedingung wahr ist oder das Timeout abläuft.

Fixtures und Projekte

Skalieren

Setup über Fixtures teilen und dieselben Tests über verschiedene Browser und Shards hinweg ausführen.

Playwright auf einen Blick

Der Kern von Playwright

page.goto

Navigiere zu einer URL und starte einen Test.

Locators

getByRole, getByLabel, getByText und getByTestId finden Elemente zuverlässig.

Web-first Assertions

expect(locator).toBeVisible() wiederholt den Check, bis er erfolgreich ist.

Aktionen

click, fill, selectOption und Tastatur-Interaktionen auf echten Elementen.

Netzwerk-Kontrolle

Requests und Responses mocken, abfangen und verifizieren.

Trace viewer

Einen Durchlauf mit Screenshots, Netzwerk-Logs und Konsole aufzeichnen und abspielen.

Eine kurze Geschichte

Von Puppeteer zu einer Cross-Browser-Plattform

  1. 2020

    Playwright veröffentlicht

    Ein Team von Puppeteer veröffentlicht eine Cross-Browser-Automatisierungsbibliothek.

    20
  2. 2021

    Playwright Test

    Ein First-Party Test Runner fügt Fixtures, Parallelität und den Trace Viewer hinzu.

    21
  3. 2022

    Codegen und UI mode

    Das Aufzeichnen von Tests und interaktives Debugging werden zu Kernfunktionen.

    22
  4. 2024

    Component Testing und mehr

    Experimentelles Component Testing und erweitertes Tooling erweitern den Funktionsumfang.

    24
  5. Heute

    Der e2e-Standard

    Weit verbreitet für zuverlässige, schnelle und debuggbare End-to-End-Suites.

    Heute

Der vollständige Leitfaden

Playwright: Alles was Sie wissen müssen

Was ist Playwright?

Playwright ist ein cross-browser end-to-end testing Framework von Microsoft. Es steuert Chromium, Firefox und WebKit über eine einzige API an, wartet automatisch, bis Elemente bereit sind, und liefert einen Test-Runner mit Fixtures, Parallelisierung, Tracing und Netzwerksteuerung mit.

Es entwickelte sich aus Puppeteer weiter und behielt die guten Aspekte bei – ein modernes Protokoll und eine saubere API –, während es echten Cross-Browser-Support und erstklassiges Tooling hinzufügte. Für Teams, die heute eine End-to-End-Suite aufsetzen, ist es die gängigste Standardwahl. Vor allem das Auto-Waiting ist der Hauptgrund dafür, dass seine Tests weniger flaky sind als bei älteren Tools.

Einen Test schreiben

Ein Test navigiert, interagiert und prüft Ergebnisse. Playwright stellt die Funktionen test und expect sowie eine page fixture bereit.

// tests/login.spec.ts
import { test, expect } from "@playwright/test";

test("user can sign in", async ({ page }) => {
  await page.goto("/login");

  await page.getByLabel("Email").fill("[email protected]");
  await page.getByLabel("Password").fill("secret");
  await page.getByRole("button", { name: "Sign in" }).click();

  await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
});

Die page fixture ist ein Browser-Tab. Aktionen wie click und fill warten darauf, dass das Element ausführbar ist, bevor sie ausgeführt werden. Daher müssen keine Pausen (sleep) eingefügt werden und es gibt keine Race Conditions.

Locators und Auto-Waiting

Locators sind lazy queries, die erst bei der Verwendung in ein Element aufgelöst werden und dies so lange wiederholen, bis das Element bereit ist. Bevorzuge benutzerorientierte Locators in dieser Reihenfolge:

  1. getByRole — Buttons, Links, Überschriften und Inputs über die accessible role und den Namen.
  2. getByLabel — Formularsteuerelemente über das Label.
  3. getByText — sichtbarer Text.
  4. getByPlaceholder, getByAltText, getByTitle — andere sichtbare Attribute.
  5. getByTestId — eine stabile Test-ID, wenn keine benutzerorientierte Option passt.
// locators.ts
page.getByRole("link", { name: "Pricing" });
page.getByLabel("Search");
page.getByText("Welcome back");
page.getByTestId("cart-total");

Da Aktionen automatisch warten (auto-wait), benötigst du selten explizite Wartezeiten. Auch Assertions sind „web-first“: expect(locator).toBeVisible() wiederholt den Vorgang, bis die Bedingung erfüllt ist oder das Timeout abläuft, was die Tests resistent gegenüber Timing-Problemen macht.

// assertions.ts
await expect(page.getByRole("alert")).toHaveText("Saved");
await expect(page.getByRole("button", { name: "Save" })).toBeEnabled();
await expect(page.getByTestId("row")).toHaveCount(3);

Fixtures und gemeinsames Setup

Das Fixture-System von Playwright ermöglicht es, Setups zu teilen, ohne sie ständig wiederholen zu müssen. Ein Fixture ist ein Wert, der in Tests injiziert wird und vom Runner erstellt sowie wieder abgebaut wird.

// fixtures.ts
import { test as base } from "@playwright/test";

export const test = base.extend({
  authenticatedPage: async ({ page }, use) => {
    await page.goto("/login");
    await page.getByLabel("Email").fill("[email protected]");
    await page.getByLabel("Password").fill("secret");
    await page.getByRole("button", { name: "Sign in" }).click();
    await use(page);
  },
});

Speziell für die Authentifizierung ist das empfohlene Muster ein Setup-Projekt, das sich einmal anmeldet, den Storage State in einer Datei speichert und diesen über verschiedene Tests hinweg wiederverwendet. Das hält die Testsuite schnell und vermeidet die ständige Wiederholung des Login-Flows.

Netzwerksteuerung

page.route fängt Anfragen ab, sodass Sie Ladezustände, Fehler und Edge-Cases testen können, ohne ein echtes Backend zu benötigen.

// mock.ts
await page.route("**/api/users", (route) =>
  route.fulfill({
    status: 500,
    body: JSON.stringify({ message: "Server error" }),
  }),
);

await page.goto("/users");
await expect(page.getByRole("alert")).toContainText("went wrong");

Sie können zudem prüfen, was die App gesendet hat, Antworten verzögern, um Ladezustände zu testen, oder Drittanbieter-Skripte blockieren, damit die Tests schnell und deterministisch bleiben.

Debugging und Tooling

Das Tooling von Playwright ist ein wesentlicher Teil seiner Attraktivität:

  • Codegen zeichnet Ihre Interaktionen auf und generiert eine Testdatei mit den entsprechenden Locators.
  • UI mode führt Tests in einer Watch-UI aus, in der Sie Aktionen Schritt für Schritt durchlaufen und den DOM inspizieren können.
  • Trace viewer zeichnet einen vollständigen Trace auf – inklusive Screenshots, DOM-Snapshots, Netzwerk- und Konsolenprotokollen –, den Sie nach einem CI-Fehler erneut abspielen können.
  • Reporters erstellen direkt HTML-, JUnit- und andere Berichte.

Insbesondere der Trace Viewer verwandelt mysteriöse CI-Fehler in ein Schritt-für-Schritt-Replay, was oft den Unterschied zwischen einem fünfminütigen Fix und einem ganzen Nachmittag voller Vermutungen ausmacht.

Parallelismus und CI

Playwright Test führt Testdateien standardmäßig parallel über Worker-Prozesse aus. Sie können dieselbe Suite über verschiedene Browser-Projekte laufen lassen, die Anzahl der Worker anpassen und eine große Suite mit --shard über mehrere Maschinen sharden. Um sicher zu parallelisieren, müssen Tests unabhängig sein und gemeinsam genutzte, veränderliche Zustände (shared mutable state) vermeiden.

Installieren Sie in der CI die Browser mit npx playwright install --with-deps, führen Sie die Suite aus und laden Sie den HTML-Report sowie die Traces als Artefakte hoch. Retries stehen für tatsächlich instabile Infrastrukturen zur Verfügung, sollten jedoch als Sicherheitsnetz dienen und nicht als Ersatz für die Behebung von Flakiness.

Wo Playwright ins Spiel kommt

End-to-End-Tests bilden die Spitze der Pyramide: Sie sind wenige, langsam und haben einen hohen Wert. Darunter liegen Komponententests mit Testing Library und schnelle Unit-Tests mit Vitest oder Jest. Playwright deckt die User Journeys ab, die nur ein echter Browser verifizieren kann – wie Authentifizierung, Checkout, Navigation und das Verhalten über verschiedene Browser hinweg.

Best Practices

  • Bevorzugen Sie Role- und Label-Locators; verwenden Sie Test-IDs nur sparsam.
  • Verlassen Sie sich auf Auto-Waiting anstatt auf waitForTimeout.
  • Halten Sie Tests unabhängig, damit sie sicher parallelisiert werden können.
  • Verwenden Sie den Storage State zur Wiederverwendung der Authentifizierung, anstatt sich jedes Mal neu anzumelden.
  • Mocken Sie das Netzwerk für Edge Cases; behalten Sie einige Tests gegen das echte Backend bei.
  • Zeichnen Sie bei Fehlern Traces auf und laden Sie diese in der CI hoch.
  • Verwenden Sie data-testid nur für Elemente ohne zugängliche Identität.

Häufige Fehler

  • Verwendung von CSS- oder XPath-Selektoren, die an Styling und Struktur gebunden sind.
  • Harte Wartezeiten mit waitForTimeout, die die Testsuite verlangsamen und Race Conditions verschleiern.
  • Teilen von State zwischen Tests, was die Parallelisierung beeinträchtigt.
  • Testen jedes Edge-Cases End-to-End, anstatt diese tiefer in der Testpyramide abzubilden.
  • Ignorieren von Traces und bloßes Raten bei CI-Fehlern.
  • Verlassen auf Retries, um echte Flakiness zu übertünchen.

Wie geht es weiter?

Playwright ist derzeit die beste Standardwahl für End-to-End-Tests. Vergleiche es mit Cypress, um eine alternative Developer Experience kennenzulernen, und baue die unteren Testebenen mit Vitest und Testing Library auf. Füge anschließend einen einzigen, kritischen User Journey als deinen ersten e2e-Test hinzu und erweitere deine Testsuite von dort aus.

Elemente finden

Role-basierte Locators entsprechen der Art und Weise, wie Nutzer und assistierende Technologien Elemente finden, und schlagen fehl, wenn das Markup nicht barrierefrei ist.

Bevorzugt
await page
  .getByRole("button", { name: "Save" })
  .click();
Vermeiden
await page
  .locator(".btn.btn-primary > span")
  .click();

Auf Elemente warten

Locators warten automatisch auf die Ausführbarkeit. Harte Timeouts (Hard Waits) sind die Hauptursache für flaky e2e-Tests.

Bevorzugt
await expect(
  page.getByText("Saved"),
).toBeVisible();
Vermeiden
await page.waitForTimeout(3000);
const text = await page
  .locator(".toast").textContent();
expect(text).toBe("Saved");

Häufig gestellte Fragen

Häufig gestellte Fragen

Keep learning

Related topics from the roadmap.

$ Lernen Sie jetzt

Bereit, Playwright zu lernen?

Unser interaktives Tutorial führt Sie Schritt für Schritt durch Playwright — mit Quizzen und echtem Code, den Sie im Browser ausführen können.