Next.js-Entwickler in Bochum

Next.js Entwickler für Unternehmen in Bochum: was die Next.js-Dokumentation zum Testen empfiehlt, warum asynchrone Server Components im Browser getestet werden, wie Server Actions geprüft werden und wie die CI vor jedem Deploy testet. Remote und schriftlich, erste Einschätzung kostenlos.

Next.js-Entwickler

Mein Platz in der WordPress-Community

  • Mein wordpress.org-Konto besteht seit 2006.
  • Ich habe zum WordPress-Core in den Versionen 7.0 und 7.1 beigetragen.
  • Ich betreue 30 Plugins auf wordpress.org.
  • Ich organisiere WordCamps und trete dort als Speaker auf.
  • Ich war bei jedem WordCamp Europe von 2017 bis 2026 dabei.

Mein WordPress.org-Profil

#Next.js in Bochum: Tests, bevor etwas live geht

Ich bin Mariusz Szatkowski, baue seit 2006 Websites mit WordPress und heute auch Frontends mit Next.js. Ich arbeite als einzelner Entwickler von Gdynia aus, remote und schriftlich: Sie beschreiben das Vorhaben, meine Rückfragen kommen per E-Mail, und am Ende steht ein Dokument mit Umfang und Annahmen. Ich komme nicht vorbei und telefoniere nicht.

Diese Seite behandelt eine Frage, die sich meist erst nach dem ersten Fehler im Betrieb stellt: Wie wird eine Next.js-Anwendung getestet, und was davon läuft vor jedem Deploy? Grundlage sind die Testanleitungen auf nextjs.org, die ich am 11. November 2026 abgerufen habe. Zu diesem Zeitpunkt lag Next.js bei Version 16.4.6, die laut npm-Registry am 9. November 2026 erschien.

#Was die Next.js-Dokumentation zum Testen empfiehlt

Die Übersicht zum Testen unterscheidet fünf Arten: Unit-Tests, Komponententests, Integrationstests, End-to-End-Tests (E2E) und Snapshot-Tests. Dazu gibt es vier Einrichtungsanleitungen. Die Tabelle fasst zusammen, wofür welches Werkzeug dort beschrieben ist:

WerkzeugBeschrieben fürHinweis aus der Anleitung
VitestUnit-Tests, zusammen mit React Testing LibraryUnterstützt asynchrone Server Components derzeit nicht
JestUnit- und Snapshot-Tests, mit eingebauter Konfiguration über next/jestUnterstützt asynchrone Server Components derzeit nicht
PlaywrightEnd-to-End-Tests in Chromium, Firefox und WebKitTests laufen gegen einen laufenden Next.js-Server
CypressEnd-to-End- und KomponententestsKomponententests unterstützen asynchrone Server Components nicht

Die Anleitungen zu Vitest und Jest waren am 25. August 2026 zuletzt aktualisiert, die zu Playwright am 15. Oktober 2026. Laut npm-Registry waren am 11. November 2026 Vitest 5.1.0 (erschienen am 2. November 2026) und @playwright/test 1.65.0 (5. November 2026) aktuell.

Meine Aufteilung: Vitest für Funktionen und synchrone Komponenten, Playwright für ganze Seiten und Abläufe. Cypress setze ich ein, wenn ein Team es schon nutzt; ein zweites Werkzeug nur wegen der Mode führe ich nicht ein.

#Warum asynchrone Server Components im Browser getestet werden

Die Übersicht sagt es knapp: Weil async-Server-Components im React-Umfeld neu sind, unterstützen manche Werkzeuge sie noch nicht vollständig, und deshalb empfiehlt Next.js für solche Komponenten End-to-End-Tests statt Unit-Tests. Die Anleitungen zu Vitest, Jest und Cypress wiederholen das jeweils in einem Hinweis.

Daraus folgt eine Arbeitsregel, die ich in jedem Projekt einhalte:

  1. Was eine Server Component an Daten braucht, steht in einer eigenen Funktion, die einfache Werte zurückgibt. Diese Funktion bekommt Unit-Tests.
  2. Die Komponente selbst bleibt dünn: Daten holen, an eine synchrone Darstellungskomponente übergeben. Die Darstellungskomponente bekommt Unit-Tests, soweit sie interaktiv ist.
  3. Dass beides auf der fertigen Seite zusammenpasst, prüft ein Playwright-Test gegen den Produktionsbuild.

Mit Cache Components gibt es außerdem den Hilfsbaustein instant() aus @next/playwright. Er prüft, was nach einer Navigation sofort sichtbar ist, bevor dynamische Inhalte nachgeladen werden. Setup und Beispiele stehen im Leitfaden zur sofortigen Navigation; wie Zwischenspeicher und Revalidierung selbst funktionieren, beschreibt meine Seite zu Next.js in Augsburg.

#Ein Beispiel aus Bochum: der Spielplan des Schauspielhauses

Ein Zeitplan mit wechselnden Zuständen ist ein gutes Testobjekt, weil jeder Zustand eine eigene Darstellung braucht. Die Spielplan-Seite des Schauspielhauses Bochum zeigte am 11. November 2026 zu den Vorstellungen unter anderem die Hinweise „Karten“, „Wenige Karten“, „evtl. Restkarten“, „Abendkasse“ und bei einer Vorstellung „Fällt aus“ (schauspielhausbochum.de). Wie diese Seite technisch gebaut ist, weiß ich nicht und beurteile es nicht. Als Beispiel für Ihre eigene Anwendung taugt sie trotzdem:

Zustand im SpielplanBeispielhafte AnforderungWo ich sie teste
Karten verfügbarLink zum Kauf ist sichtbarPlaywright, ganze Seite
Wenige KartenHinweis erscheint, Kauf bleibt möglichUnit-Test der Darstellung
Fällt ausKein Kauflink, Hinweis ist sichtbarUnit-Test und ein Browser-Test
Filter aktivNur passende Vorstellungen, Zähler stimmtPlaywright mit festen Testdaten

das Schauspielhaus von Bochum am Hans-Schalla-Platz, hinten links die Saladin-Schmitt-Straße, rechts die Königsallee

Foto: GeorgDerReisende, CC BY-SA 4.0, Wikimedia Commons.

Dasselbe Muster gilt für Lagerbestand im Shop, Öffnungszeiten, Terminlisten oder Stellenanzeigen mit Ablaufdatum: Jeder Zustand ist ein Testfall, und die Tests laufen mit festen Beispieldaten, nicht mit dem, was gerade im System steht.

#Server Actions testen: Zugriff und Eigentum

Eine Server Action ist eine Funktion, die auf dem Server läuft und aus Formularen aufgerufen wird. Die Dokumentation weist darauf hin, dass eine exportierte Action per direktem POST-Request erreichbar ist, nicht nur über die Oberfläche, und dass Authentifizierung und Berechtigung deshalb in jede Action gehören (Data Security, Server Actions). Das ist die wichtigste Eigenschaft, die ein Test festhalten sollte: Auch ohne Formular darf niemand fremde Daten ändern.

Eine Datei mit 'use server' ist für den Test ein gewöhnliches Modul. Ich importiere die Funktion direkt, ersetze Anmeldung und Datenbank durch Attrappen und prüfe die drei Fälle, auf die es ankommt. Die Action folgt dem Muster aus der Dokumentation:

// app/items/actions.ts
'use server'

import { revalidatePath } from 'next/cache'
import { auth } from '@/lib/auth'
import { db } from '@/lib/db'

export async function completeItem(itemId: string) {
  const session = await auth()
  if (!session?.user) throw new Error('Unauthorized')

  const item = await db.item.findFirst({
    where: { id: itemId, ownerId: session.user.id },
  })
  if (!item) throw new Error('Forbidden')

  await db.item.update({ where: { id: item.id }, data: { completed: true } })
  revalidatePath('/items')
}

Der Test dazu:

// app/items/actions.test.ts
import { beforeEach, expect, test, vi } from 'vitest'
import { completeItem } from './actions'
import { auth } from '@/lib/auth'
import { db } from '@/lib/db'

vi.mock('next/cache', () => ({ revalidatePath: vi.fn() }))
vi.mock('@/lib/auth', () => ({ auth: vi.fn() }))
vi.mock('@/lib/db', () => ({
  db: { item: { findFirst: vi.fn(), update: vi.fn() } },
}))

beforeEach(() => vi.clearAllMocks())

test('ohne Sitzung wird nichts geschrieben', async () => {
  vi.mocked(auth).mockResolvedValue(null)
  await expect(completeItem('42')).rejects.toThrow('Unauthorized')
  expect(db.item.update).not.toHaveBeenCalled()
})

test('ein fremder Datensatz wird abgelehnt', async () => {
  vi.mocked(auth).mockResolvedValue({ user: { id: 'u1' } })
  vi.mocked(db.item.findFirst).mockResolvedValue(null)
  await expect(completeItem('42')).rejects.toThrow('Forbidden')
  expect(db.item.update).not.toHaveBeenCalled()
})

test('der Eigentümer darf abschließen', async () => {
  vi.mocked(auth).mockResolvedValue({ user: { id: 'u1' } })
  vi.mocked(db.item.findFirst).mockResolvedValue({ id: '42' })
  await completeItem('42')
  expect(db.item.update).toHaveBeenCalledWith({
    where: { id: '42' },
    data: { completed: true },
  })
})

Ich habe dieses Beispiel mit Next.js 16.4.6 und Vitest 5.1.0 ausgeführt: alle drei Tests laufen durch. Die Attrappe für next/cache ist nötig. Ohne sie bricht der dritte Test mit „Invariant: static generation store missing in revalidatePath“ ab, weil revalidatePath außerhalb einer Next.js-Anfrage nicht läuft. Dass die Cache-Auffrischung tatsächlich greift, prüft deshalb der Browser-Test, nicht der Unit-Test.

#Dieselbe Action im Browser: ein Playwright-Test

Der Browser-Test spielt den Weg des Nutzers durch. Er findet Felder über ihre Beschriftung und Schaltflächen über ihre Rolle, nicht über CSS-Klassen. So übersteht er Änderungen am Layout, und er prüft nebenbei, ob die Formularfelder überhaupt beschriftet sind:

// tests/kontakt.spec.ts
import { test, expect } from '@playwright/test'

test('das Formular meldet den Erfolg', async ({ page }) => {
  await page.goto('/kontakt')
  await page.getByLabel('E-Mail').fill('[email protected]')
  await page.getByLabel('Nachricht').fill('Testnachricht')
  await page.getByRole('button', { name: 'Senden' }).click()
  await expect(page.getByText('Vielen Dank')).toBeVisible()
})

Die Konfiguration startet den Server selbst. Die Option webServer mit reuseExistingServer: !process.env.CI stammt aus der Playwright-Dokumentation:

// playwright.config.ts
import { defineConfig } from '@playwright/test'

export default defineConfig({
  testDir: './tests',
  use: { baseURL: 'http://localhost:3000' },
  webServer: {
    command: 'npm run start',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
  },
})

Vorher muss npm run build gelaufen sein. Die Next.js-Anleitung empfiehlt, gegen den Produktionscode zu testen, weil sich die Anwendung dort so verhält wie im Betrieb.

#Tests vor jedem Deploy: die CI

Ein Test, den niemand startet, schützt nichts. Deshalb laufen die Tests bei jedem Pull Request und vor jedem Deploy in der CI. Die Playwright-Anleitung für GitHub Actions liefert das Gerüst: Repository auschecken, Node einrichten, npm ci, Browser installieren, npx playwright test, Bericht hochladen. Ich ergänze Unit-Tests, den Build und den Cache für .next/cache, den die Next.js-Anleitung zum CI-Build-Cache für GitHub Actions beschreibt:

name: Tests
on:
  pull_request:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: lts/*
          cache: npm
      - uses: actions/cache@v4
        with:
          path: ${{ github.workspace }}/.next/cache
          key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
          restore-keys: |
            ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
      - run: npm ci
      - run: npx vitest run
      - run: npm run build
      - run: npx playwright install --with-deps
      - run: npx playwright test
      - uses: actions/upload-artifact@v5
        if: ${{ !cancelled() }}
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - run: ./scripts/deploy.sh # der Deploy-Befehl Ihres Hosters

Entscheidend ist needs: test: Der Deploy-Job startet nur, wenn alle Tests grün waren. Die Playwright-Anleitung setzt kein Zeitlimit für den Job, sondern empfiehlt globalTimeout in der Konfiguration, damit auch bei einem Abbruch noch ein Bericht entsteht. Welchen Wert Sie dort eintragen, hängt von der Größe Ihrer Suite ab.

Was kein Test abdeckt: Die Next.js-Dokumentation beschreibt, dass ein Browser mit altem Stand nach einem Deploy eine Server Action aufrufen kann, deren Kennung nicht mehr existiert. Der Fehler heißt „Failed to find Server Action“. Die Dokumentation empfiehlt dagegen gestaffelte Deploys und eine Wiederholungsmöglichkeit in der Oberfläche. Das plane ich im Deploy ein, es ist keine Frage der Tests.

#Testdaten und Datenschutz

Tests brauchen Daten, und die Versuchung ist groß, eine Kopie der Produktion zu nehmen. Ich arbeite mit erfundenen Datensätzen, die im Repository liegen. Rechtlich geht es um den Grundsatz der Datenminimierung: Personenbezogene Daten müssen dem Zweck angemessen und auf das notwendige Maß beschränkt sein (Art. 5 Abs. 1 Buchst. c DSGVO). Für Testumgebungen ist das ein starkes Argument für erfundene Daten. Ob in Ihrem Fall etwas anderes zulässig wäre, klären Sie mit Ihrer Datenschutzberatung.

Zuständige Aufsichtsbehörde für Unternehmen in Bochum ist die Landesbeauftragte für Datenschutz und Informationsfreiheit Nordrhein-Westfalen (LDI NRW). Auch Fehlerberichte und Testprotokolle der CI können personenbezogene Daten enthalten, etwa wenn ein Test eine echte Adresse in eine Fehlermeldung schreibt. Deshalb halte ich Zugangsdaten und echte Adressen aus Testausgaben heraus.

#Checkliste für Ihr Next.js-Projekt

  • Welche Next.js-Version steht in der package.json, und welche Version gilt aktuell?
  • Gibt es eine Testsuite, und läuft sie in der CI bei jedem Pull Request?
  • Sind Datenabfragen aus Server Components in eigene Funktionen ausgelagert, die ein Unit-Test aufrufen kann?
  • Hat jede Server Action Prüfungen für Anmeldung und Eigentum, und gibt es Tests für beides?
  • Prüft ein Browser-Test die wichtigsten Abläufe (Anfrageformular, Anmeldung, Bestellung) gegen den Produktionsbuild?
  • Wird in Formularen mit Datei-Upload die Größe geprüft? Server Actions begrenzen den Request laut Dokumentation standardmäßig auf 1 MB.
  • Startet der Deploy erst, wenn die Tests grün sind?
  • Enthalten Testdaten und CI-Berichte keine echten personenbezogenen Daten?

#So läuft ein Auftrag aus Bochum bei mir

  1. Ihre Nachricht. Per Kontaktformular oder E-Mail: Anwendung, Ziel, Termin.
  2. Meine Rückfragen. Schriftlich, meist zu Version, Repository, vorhandenen Tests und Hosting.
  3. Ein Dokument mit Umfang. Leistungen, Ausschlüsse und Annahmen. Gearbeitet wird erst nach Ihrer schriftlichen Bestätigung; ein neuer Wunsch wird getrennt eingeschätzt.
  4. Testumgebung. Jede Änderung läuft zuerst dort, mit grüner CI, bevor sie in den Betrieb geht.
  5. Abnahme. Sie prüfen gegen den vereinbarten Umfang und schicken offene Punkte als Liste.
  6. Danach. Auf Wunsch betreue ich die Anwendung weiter, nach den Regeln der Wartung in Bochum: getestete Updates, Sicherungen außerhalb des Hosting-Kontos, ein schriftlicher Monatsbericht. Stunden eines Monats übertragen sich nicht.

Was Sie mitbringen: Gestaltung, Mockups und Wireframes liefern Sie oder Ihre Agentur; ich setze sie um und entwerfe nichts selbst. Gibt es noch kein Layout, tragen Sie in meiner Tabellenvorlage je Ansicht ein, welches Element wohin kommt. Ich brauche Zugang zum Repository und zum Hosting.

#Verwandte Seiten für Bochum

#Fragen aus Bochumer Anfragen

#Vitest oder Jest für ein neues Next.js-Projekt?

Beide sind in der Next.js-Dokumentation als Werkzeuge für Unit-Tests beschrieben, und beide unterstützen asynchrone Server Components nicht. Für ein neues Projekt nehme ich Vitest, weil die Einrichtung kurz ist. Eine bestehende Jest-Suite lasse ich stehen: Ein Wechsel bringt keine neuen Testfälle, nur Aufwand.

#Warum werden asynchrone Server Components nicht per Unit-Test geprüft?

Weil die Werkzeuge sie laut Next.js-Dokumentation nicht vollständig unterstützen. Die Dokumentation empfiehlt deshalb End-to-End-Tests für asynchrone Komponenten. Ich lagere die Logik daneben in einfache Funktionen aus, die ein Unit-Test direkt aufrufen kann, und prüfe die fertige Seite im Browser.

#Reicht es, eine Server Action nur über das Formular zu testen?

Nein. Eine exportierte Server Action ist per direktem POST erreichbar, auch ohne das Formular. Deshalb prüfe ich die Berechtigung zusätzlich auf der Ebene der Funktion: ohne Sitzung wird nichts geschrieben, ein fremder Datensatz wird abgelehnt. Das Formular im Browser testet dann nur noch den Weg des Nutzers.

#Sollen die Browser-Tests gegen den Entwicklungsserver laufen?

Besser gegen den Produktionsbuild. Die Playwright-Anleitung in der Next.js-Dokumentation empfiehlt, mit npm run build und npm run start zu testen, weil sich die Anwendung so wie im Betrieb verhält. Der Entwicklungsserver ist für die tägliche Arbeit gedacht.

#Dürfen echte Kundendaten in die Testumgebung?

Ich arbeite mit erfundenen Testdaten. Ob eine Kopie von Produktivdaten zulässig wäre, entscheiden Sie mit Ihrer Datenschutzberatung. Art. 5 Abs. 1 Buchst. c DSGVO verlangt, dass Daten auf das notwendige Maß beschränkt bleiben; Testdaten aus dem Produktivsystem sind selten notwendig.

#Was brauche ich von Ihnen für die erste Einschätzung?

Die Adresse der Anwendung, die Next.js-Version aus der package.json, die vorhandenen Tests (falls es welche gibt), den Ort des Repositorys und den Weg bis zum Deploy. Ein vorhandenes Layout hängen Sie an; die Elemente und ihre Platzierung liefern Sie, ich setze sie um.

#Schreiben Sie mir zu Ihrer Next.js-Anwendung

Ob ein Portal, das bisher ohne Tests ausgeliefert wird, ein Shop-Frontend vor dem nächsten Versionssprung oder ein Formular, das nach jedem Update zuverlässig funktionieren soll: Schreiben Sie mir über das Kontaktformular. Nennen Sie die Adresse der Anwendung, das Ziel, den gewünschten Termin und den Stack, mit dem Sie heute arbeiten. An Werktagen antworte ich schriftlich; die erste Einschätzung ist kostenlos.

Brauchen Sie die Leistung: Next.js-Entwickler in Bochum?

Beschreiben Sie Ihr Projekt per E-Mail. Antwort innerhalb von 48 Stunden.

Projekt beschreiben

Weitere WordPress-Dienste und Wissensbasis entdecken