Next.js 15 Testing: Playwright vs. Vitest
Stabiler Code ist kein Zufall. Wir vergleichen Vitest für Unit-Tests und Playwright für E2E-Tests in Next.js 15 und zeigen dir den perfekten Workflow.
Nichts ist frustrierender als ein Bug, der eine Funktion zerschießt, die eigentlich schon seit Wochen fertig war. In der professionellen Softwareentwicklung ist "Hoffen, dass es klappt" keine Strategie. Wir brauchen automatisierte Tests, um sicherzustellen, dass unser Code auch nach dem zehnten Refactoring noch genau das tut, was er soll.
Mit Next.js 15 hat sich das Ökosystem weiter konsolidiert. Zwei Tools haben sich als Goldstandard herauskristallisiert: Vitest für schnelle Unit-Tests und Playwright für echte Browser-Simulationen (End-to-End). In diesem Guide schauen wir uns an, wie du beide Tools effizient kombinierst.
Vitest: Der Sprinter für deine Logik
Vitest ist der moderne Nachfolger von Jest. Es ist blitzschnell und versteht TypeScript von Haus aus, ohne dass du mühsame Konfigurationen wie ts-jest oder babel vornehmen musst. Nutze Vitest für alles, was keine komplette Browser-Umgebung braucht: Helper-Funktionen, mathematische Validierungen oder einfache Komponenten-Tests.
Ein einfacher Test für eine Warenkorb-Berechnung sieht so aus:
import { expect, test, describe } from 'vitest'
import { calculateTotal } from './cart-logic'
describe('Warenkorb Logik', () => { test('berechnet den Gesamtpreis korrekt bei mehreren Artikeln', () => { const items = [ { price: 10, quantity: 2 }, { price: 5, quantity: 1 } ] expect(calculateTotal(items)).toBe(25) })
test('gibt 0 zurück bei leerem Warenkorb', () => { expect(calculateTotal([])).toBe(0) }) })
Der Vorteil: Hunderte solcher Tests laufen in wenigen Sekunden durch. Du bekommst sofort Feedback in deinem Terminal, oft schon während du noch tippst (Watch Mode).
## Playwright: Der Türsteher für deine App
Unit-Tests sind toll, aber sie haben einen blinden Fleck: Sie merken nicht, wenn ein Button hinter einem anderen Element verschwindet, der API-Server nicht erreichbar ist oder die CSS-Stile den Login-Prozess unmöglich machen. Hier kommt **Playwright** ins Spiel.
Playwright öffnet einen echten Browser (Chromium, Firefox oder Safari) und klickt sich wie ein echter Nutzer durch deine Seite.
```typescript
import { test, expect } from '@playwright/test'
test('Nutzer-Flow: Anmeldung und Dashboard', async ({ page }) => {
// Gehe zur Login-Seite
await page.goto('/login')
// Fülle das Formular aus
await page.fill('input[name="email"]', 'test@example.com')
await page.fill('input[name="password"]', 'geheim123')
// Klicke auf den Button
await page.click('button[type="submit"]')
// Verifiziere das Ergebnis
await expect(page).toHaveURL('/dashboard')
await expect(page.locator('h1')).toContainText('Willkommen zurück')
})
Meine Meinung: Wenn du wenig Zeit hast, schreibe keine 100 Unit-Tests. Schreibe stattdessen 5 Playwright-Tests für deine absolut kritischen Pfade (Login, Payment, Signup). Das gibt dir die größte Sicherheit vor einem kompletten Systemausfall.
Mocking: Wenn die API noch nicht fertig ist
Ein häufiges Problem beim Testen: Deine App braucht Daten von einer API (z.B. Supabase), aber du willst den echten Server nicht bei jedem Test belasten.
Für Vitest empfehle ich Mock Service Worker (MSW). Damit "fängst" du die Netzwerk-Anfragen ab und schickst vordefinierte Test-Daten zurück. So kannst du auch Fehlerzustände (z.B. ein 500-Error vom Server) testen, ohne deinen echten Server manipulieren zu müssen.
CI/CD: Tests automatisieren
Tests sind nur nützlich, wenn sie auch ausgeführt werden. Nutze GitHub Actions, um deine Tests bei jedem Push automatisch laufen zu lassen. Wenn ein Test fehlschlägt, darf der Code nicht in den main-Branch gemergt werden.
Hier ein minimalistisches Beispiel für eine .github/workflows/test.yml:
name: CI
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm install
- run: npm run test:unit
- run: npx playwright install --with-deps
- run: npm run test:e2e
Die goldene Regel: Die Test-Pyramide
Versuche nicht, alles mit Playwright zu testen – das wird auf Dauer zu langsam, teuer und instabil (Flakiness). Nutze das Prinzip der Pyramide:
- Basis (Viele): Unit-Tests mit Vitest (Logik, reine Funktionen).
- Mitte (Einige): Integrations-Tests (Zusammenspiel mehrerer Komponenten).
- Spitze (Wenige): End-to-End-Tests mit Playwright (Kritische User-Flows).
Fazit: Testen macht dich zu einem besseren Entwickler
Am Anfang fühlt sich Testen oft wie eine Bremse an. Man schreibt "doppelten" Code und kämpft mit Konfigurationen. Aber: Nach dem dritten Mal, bei dem ein Test einen kritischen Bug vor dem Release gefunden hat, wirst du nie wieder ohne arbeiten wollen.
Ein gut getestetes Projekt ist ein Projekt, bei dem du am Freitag um 16:00 Uhr noch ein Feature releasen kannst, ohne das ganze Wochenende Angst vor Fehlermeldungen haben zu müssen.
Verwandte Themen für Profis:
FAQ zu diesem Artikel
d6benjamin
Willkommen auf d6b