Intent-Based Testing erklärt: Warum du Tests in Plain English schreiben solltest

Tests in Plain English statt Code: Intent-Based Testing eliminiert Test-Maintenance und macht Verification so einfach wie das Beschreiben, was funktionieren soll.

Intent-Based Testing erklärt: Warum du Tests in Plain English schreiben solltest

Tests in Plain English statt in Code: aletiq verify "Users can complete checkout" statt 50 Zeilen Playwright mit Selektoren, Assertions und Page Objects. Intent-Based Testing eliminiert die Maintenance-Last klassischer Tests und macht Verification so einfach wie das Beschreiben dessen, was funktionieren soll.

Dieser Artikel erklärt das Konzept von Grund auf: wie du gute Intents schreibst, warum Plain English präzise genug ist, wie du von bestehenden Tests migrierst — und wo klassische Tests weiterhin die bessere Wahl bleiben.

Was ist Intent-Based Testing?

Intent-Based Testing beschreibt, was Software tun soll — nicht wie sie es tun soll. Die Testsprache ist natürliche Sprache statt Programmiercode.

Klassischer E2E-Test:

await page.goto('https://myapp.com');
await page.locator('[data-testid="login-email"]').fill('user@test.com');
await page.locator('[data-testid="login-password"]').fill('password123');
await page.locator('[data-testid="login-submit"]').click();
await expect(page.locator('[data-testid="dashboard-welcome"]')).toBeVisible();
await expect(page.locator('[data-testid="dashboard-welcome"]')).toContainText('Welcome');

Intent-Based Test:

aletiq verify "A user should be able to log in and see their dashboard" --url https://myapp.com

Beide prüfen dasselbe: Funktioniert der Login? Aber der Intent ist an Verhalten gekoppelt, nicht an Selektoren. Wenn ein AI-Agent die Login-Komponente komplett umschreibt — neue Klassen, andere Struktur, geändertes Layout — bleibt der Intent gültig. Der Playwright-Test bricht.

Intent-Based Testing verschiebt den Fokus von „Ist der Code korrekt?" zu „Erfüllt die Software ihren Zweck?" Das ist ein fundamentaler Perspektivwechsel: Du testest nicht mehr deine Implementierung, sondern dein Produkt.

Warum ist Testcode fast so aufwändig wie Feature-Code?

Weil gute E2E-Tests eigene Architektur, Abstraktion und Wartung erfordern — Aufwand, den die meisten Teams unterschätzen.

Was in einer „richtigen" Playwright-Suite steckt:

  • Page Objects — Abstraktionen für jede Seite deiner App. Jedes Page Object kapselt Selektoren und Interaktionen. Bei 20 Seiten: 20 Page-Object-Dateien, die bei jedem UI-Change aktualisiert werden müssen.
  • Fixtures und Test Data — Testdaten müssen angelegt, verwaltet und nach jedem Test aufgeräumt werden. Datenbank-Seeds, API-Mocks, Authentifizierungs-Tokens.
  • Selektoren — Jedes interaktive Element braucht einen stabilen Selektor. data-testid-Attribute müssen im Produktionscode gepflegt werden — Testcode dringt in Feature-Code ein.
  • Assertions — Jeder erwartete Zustand muss explizit geprüft werden. Vergiss eine Assertion, und ein Fehler rutscht durch. Schreib zu viele, und der Test bricht bei jeder kosmetischen Änderung.
  • Flaky-Test-Debugging — Tests die mal grün, mal rot sind. Race Conditions, Timing-Probleme, instabile Netzwerk-Requests. Flaky Tests sind die zeitintensivste Kategorie der Test-Maintenance.
  • CI-Konfiguration — Browser-Binaries, parallele Ausführung, Retries, Screenshot-on-Failure, Artifact-Upload. Die Pipeline will konfiguriert und gewartet werden.

Erfahrungswerte zeigen: 30 bis 40 Prozent der gesamten Testing-Zeit eines Teams fließt in Maintenance bestehender Tests. Bei schnellen Iterationszyklen — besonders mit AI-Agents — kann dieser Anteil auf über 50 Prozent steigen.

Intent-Based Testing eliminiert diesen gesamten Stack. Keine Page Objects, keine Fixtures, keine Selektoren, keine Flaky Tests. Nur Sätze, die beschreiben, was funktionieren soll.

Wie schreibe ich einen guten Intent?

Mit einer einfachen Formel: Wer + was + erwartetes Ergebnis. Je spezifischer, desto besser das Verdict.

Schlechte Intents (zu vage):

# Zu vage — was heißt "work"?
aletiq verify "The page should work" --url https://myapp.com

# Zu vage — was heißt "correct"?
aletiq verify "The form should be correct" --url https://myapp.com/contact

# Zu breit — zu viel auf einmal
aletiq verify "Everything should function properly" --url https://myapp.com

Gute Intents (spezifisch und verhaltensbezogen):

# Wer: User, Was: CTA klicken, Ergebnis: auf Pricing-Seite landen
aletiq verify "The main CTA should navigate the user to the pricing page" --url https://myapp.com

# Wer: User, Was: Formular ausfüllen, Ergebnis: Erfolgsmeldung
aletiq verify "The contact form should be submittable and show a success message" --url https://myapp.com/contact

# Wer: eingeloggter User, Was: Dashboard öffnen, Ergebnis: Daten sichtbar
aletiq verify "The dashboard should display the user's project list after login" --url https://myapp.com/dashboard

Tipps für bessere Intents:

  • Verhaltenswörter verwenden — „navigate to", „display", „submit", „load", „show" statt „be correct" oder „work"
  • Ein Intent pro Verhalten — Nicht „Login should work and dashboard should load and settings should be accessible". Trenne das in drei Intents.
  • Ergebnis benennen — Nicht „User clicks signup" (das ist eine Aktion, kein Test). Sondern: „User should be able to create an account via the signup form" (das beschreibt das erwartete Ergebnis).
  • Perspektive des Users — Formuliere aus Nutzersicht, nicht aus Code-Sicht. „The user should see their order history" statt „The OrderList component should render items from the API".

Was macht einen Intent besser als eine Assertion?

Drei fundamentale Vorteile, die aus der Natur natürlicher Sprache folgen:

1. Intents sind stabil über Rewrites

Eine Assertion prüft: expect(page.locator('.cart-count')).toHaveText('3'). Wenn der AI-Agent die Klasse in .basket-items umbenennt: Test bricht.

Ein Intent prüft: „The shopping cart should show the number of items." Egal wie die Klasse heißt, egal ob es ein Badge, ein Counter oder ein Text ist — solange die Anzahl sichtbar ist: PASS.

2. Intents prüfen Verhalten, nicht Details

Eine Assertion prüft einen exakten Wert an einer exakten Stelle. Ein Intent prüft, ob das Gesamtverhalten stimmt. Das ist eine höhere Abstraktionsebene — und genau die richtige für E2E-Verification.

Analogie: Du prüfst ein Restaurant nicht, indem du misst, ob der Teller exakt 24 cm Durchmesser hat. Du prüfst, ob das Essen gut schmeckt und der Service freundlich ist. Intents testen das Restaurant-Erlebnis, Assertions messen den Teller.

3. Intents brauchen kein DOM-Wissen

Um eine Playwright-Assertion zu schreiben, musst du wissen: Welches Element? Welcher Selektor? Welches Attribut? Welcher erwartete Wert? Das erfordert Kenntnis der Implementierung.

Um einen Intent zu schreiben, musst du nur wissen: Was soll der User tun können? Das ist Produktwissen, kein Implementierungswissen. Product Owner, Designer und QA-Manager können Intents formulieren — Playwright-Tests können nur Entwickler schreiben.

Kann Plain English wirklich präzise genug für Tests sein?

Ja — wenn du spezifisch formulierst. Die Precision hängt nicht von der Sprache ab, sondern von der Formulierung.

Vage = unpräzise (in jeder Sprache):

# Vager Intent — zu viel Interpretationsspielraum
aletiq verify "The page should look good" --url https://myapp.com

Spezifisch = präzise (auch in Plain English):

# Spezifischer Intent — klares erwartetes Ergebnis
aletiq verify "The hero section should display a headline, a subheadline, and a CTA button that navigates to /signup" --url https://myapp.com

Die Multi-Model-Jury (Claude, Gemini, GPT) versteht natürliche Sprache mit hoher Nuance. „Should navigate to pricing" wird nicht als „Seite enthält das Wort Pricing" interpretiert, sondern als „Klick auf das Element führt zur Pricing-Seite". Die Jury bewertet semantisch, nicht lexikalisch.

Wo Plain English tatsächlich an Grenzen stößt:

  • Exakte numerische Werte: „Zeigt genau 42 Ergebnisse" — hier ist eine programmierte Assertion präziser
  • Timing-Anforderungen: „Lädt in unter 200ms" — Performance-Tests brauchen Code
  • Pixel-genaue Positionierung: „Button ist 24px vom rechten Rand entfernt" — dafür braucht es Screenshot-Diffing

Für alles andere — und das ist 80 bis 90 Prozent der typischen E2E-Tests — ist Plain English nicht nur ausreichend, sondern besser, weil es wartungsfrei ist.

Wie sehen Intents für typische Web-App-Flows aus?

Konkrete Beispiel-Intents, die du direkt für dein Projekt adaptieren kannst:

Authentication:

aletiq verify "A new user should be able to create an account via the signup form" --url https://myapp.com/signup
aletiq verify "An existing user should be able to log in and reach the dashboard" --url https://myapp.com/login
aletiq verify "The forgot-password flow should send a reset link" --url https://myapp.com/forgot-password

Dashboard / SaaS:

aletiq verify "The dashboard should display the user's projects with name and status" --url https://myapp.com/dashboard
aletiq verify "Creating a new project should add it to the project list" --url https://myapp.com/dashboard
aletiq verify "The settings page should allow updating the user's email address" --url https://myapp.com/settings

E-Commerce:

aletiq verify "Product pages should display price, description, and an add-to-cart button" --url https://myshop.com/products/123
aletiq verify "The cart should update when adding or removing items" --url https://myshop.com/cart
aletiq verify "The checkout flow should be completable with valid payment information" --url https://myshop.com/checkout

Landing Page:

aletiq verify "The hero CTA should navigate to the signup page" --url https://myapp.com
aletiq verify "The pricing section should display all available plans" --url https://myapp.com/#pricing
aletiq verify "The navigation should lead to all major sections" --url https://myapp.com

Jeder dieser Intents ist in unter 30 Sekunden formuliert und bleibt stabil über Monate und Jahre — unabhängig davon, wie oft die Implementierung sich ändert.

Was ist ein Profile und warum macht es Intents intelligenter?

Ein Profile gibt Aletiq Kontext über dein Projekt. Ohne Profile bewertet die Judge-Jury generisch. Mit Profile versteht sie, was deine App ist und was sie tun soll.

Ohne Profile:

Intent: „The main CTA should work correctly."

Judge denkt: „Ein CTA existiert und ist klickbar. PASS." — Aber wohin soll er führen? Was ist „korrekt" für diese App?

Mit Profile:

Profile: „SaaS project management tool. The landing page converts visitors to free trial signups. The main CTA should always lead to /signup."

Jetzt denkt der Judge: „Der CTA führt zu /pricing statt /signup. Laut Profile soll er zu Signups führen. FAIL." — Der Judge kennt den Zweck deiner App und kann gewollte Änderungen von Bugs unterscheiden.

Was in ein Profile gehört:

  • Was die App tut (in 1-2 Sätzen)
  • Wer die Zielgruppe ist
  • Was die kritischen Conversion-Pfade sind
  • Welche Pages welchen Zweck erfüllen

Das Profile ist kein Test-Code — es ist eine Beschreibung deines Produkts in natürlicher Sprache. Einmal geschrieben, selten aktualisiert. Es macht jeden Intent intelligenter, weil der Judge jetzt Kontext hat.

Mehr zu Profiles und der Judge-Architektur: Screenshot-Diffing vs. Intent-Based Verification.

Wie migriere ich von Playwright-Tests zu Intents?

Schrittweise — du musst nicht alles auf einmal umstellen. Drei Schritte für eine saubere Migration:

Schritt 1: Extrahiere die Intention aus bestehenden Tests

Lies jeden Playwright-Test und frage: „Was prüft dieser Test eigentlich?" Nicht technisch, sondern aus User-Sicht.

// Playwright-Test
test('checkout flow', async ({ page }) => {
  await page.goto('/products/1');
  await page.getByTestId('add-to-cart').click();
  await page.goto('/cart');
  await page.getByTestId('checkout-btn').click();
  await page.getByTestId('email').fill('test@test.com');
  await page.getByTestId('submit-order').click();
  await expect(page.getByTestId('success')).toBeVisible();
});

// Extrahierte Intention:
// "A user should be able to add a product to the cart and complete checkout"

Schritt 2: Formuliere als Intent

aletiq verify "A user should be able to add a product to cart and complete the checkout flow" --url https://myshop.com/products/1

Schritt 3: Parallelbetrieb, dann schrittweise ersetzen

Lass Playwright-Tests und Aletiq-Intents parallel laufen. Wenn ein Playwright-Test wegen eines Selector-Changes fehlschlägt und der entsprechende Aletiq-Intent PASS zeigt — weißt du, dass die Funktion intakt ist und nur der Test veraltet war. Das ist der Moment, in dem du den Playwright-Test durch den Intent ersetzt.

Muss ich alle meine Tests durch Intents ersetzen?

Nein — die beste Strategie ist hybrid. Verschiedene Test-Typen für verschiedene Zwecke.

Durch Intents ersetzen:

  • E2E-Smoke-Tests: „Funktioniert Login?", „Funktioniert Checkout?" — perfekt für Intents
  • Navigation-Tests: „Alle Links führen zu den richtigen Seiten" — Intents sind stabiler als Selector-basierte Tests
  • UI-Regression-Tests: „Sieht die Pricing-Seite noch korrekt aus und zeigt alle Pläne?" — Intent statt Screenshot-Diff

Als klassische Tests behalten:

  • Unit-Tests — Isolierte Funktionslogik (Preisberechnung, Validierung, Datenformatierung). Unit-Tests sind schnell, deterministisch und an Logik gekoppelt, nicht an UI.
  • Integration-Tests — API-Endpunkte, Datenbank-Queries, Service-Interaktionen. Diese brauchen programmierte Assertions mit exakten Werten.
  • Performance-Tests — Ladezeiten, Bundle-Größe, API-Latenz. Numerische Messungen erfordern Code.
  • Accessibility-Tests — WCAG-Compliance, Aria-Labels, Keyboard-Navigation. Spezialisierte Tools (axe, Lighthouse) sind hier besser.

Die Faustregel: Wenn der Test fragt „Funktioniert das Feature?" → Intent. Wenn der Test fragt „Hat diese Funktion den korrekten Rückgabewert?" → Unit-Test. Wenn der Test fragt „Wie schnell lädt die Seite?" → Performance-Test.

Mehr zur Abgrenzung zwischen Intent-Verification und Playwright: Playwright vs. Aletiq. Und zum praktischen Workflow mit AI-Agents: Wie teste ich Code, den mein AI-Agent geschrieben hat?

Wie starte ich mit Intent-Based Testing?

In 10 Minuten — von null auf verifizierte App:

Schritt 1: Identifiziere deine 5 kritischsten Flows

Frage dich: „Wenn ein Kunde morgen anruft und sagt ‚XYZ funktioniert nicht' — was wäre am schlimmsten?" Das sind deine ersten 5 Intents.

Schritt 2: Formuliere die Intents

aletiq verify "New users can create an account" --url https://myapp.com/signup
aletiq verify "The main dashboard loads with real data" --url https://myapp.com/dashboard
aletiq verify "The pricing page shows all plans with working CTAs" --url https://myapp.com/pricing
aletiq verify "The checkout flow is completable" --url https://myapp.com/checkout
aletiq verify "The navigation leads to all major sections" --url https://myapp.com

Schritt 3: Verifiziere

Führe die 5 Intents aus. 5 × 4,5 Sekunden = unter 25 Sekunden. Du hast sofort ein Bild davon, ob deine kritischen Flows funktionieren.

Schritt 4: Integriere in deinen Workflow

Als MCP-Tool für deinen AI-Agent, als CI-Gate in GitHub Actions, oder einfach als manuellen Check nach größeren Änderungen. Wie du Aletiq als MCP-Server einrichtest: MCP-Server für Testing. Wie der Workflow mit Claude Code, Cursor und Copilot aussieht: Claude Code vs. Cursor vs. Copilot.

Free Tier: 50 Verifications pro Monat. Genug für 10 Intents × 5 Runs. Keine Kreditkarte, kein Commitment.

Schreibe deinen ersten Intent jetzt — in 30 Sekunden formuliert, in 5 Sekunden verifiziert. So einfach sollte Testing immer gewesen sein.