Jest mit Next.js einrichten

Jest und React Testing Library werden häufig zusammen für Unit-Tests und Snapshot-Tests verwendet. Diese Anleitung zeigt Ihnen, wie Sie Jest mit Next.js einrichten und Ihre ersten Tests schreiben.

Gut zu wissen: Da async Server-Komponenten neu im React-Ökosystem sind, unterstützt Jest diese derzeit nicht. Während Sie weiterhin Unit-Tests für synchrone Server- und Client-Komponenten durchführen können, empfehlen wir die Verwendung von E2E-Tests für async-Komponenten.

Schnellstart

Sie können create-next-app mit dem Next.js with-jest-Beispiel verwenden, um schnell loszulegen:

Terminal
npx create-next-app@latest --example with-jest with-jest-app

Manuelle Einrichtung

Seit der Veröffentlichung von Next.js 12 verfügt Next.js über eine integrierte Konfiguration für Jest.

Um Jest einzurichten, installieren Sie jest und die folgenden Pakete als Dev-Abhängigkeiten:

Terminal
npm install -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node @types/jest
# oder
yarn add -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node @types/jest
# oder
pnpm install -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node @types/jest

Generieren Sie eine grundlegende Jest-Konfigurationsdatei, indem Sie den folgenden Befehl ausführen:

Terminal
npm init jest@latest
# oder
yarn create jest@latest
# oder
pnpm create jest@latest

Dies führt Sie durch eine Reihe von Eingabeaufforderungen, um Jest für Ihr Projekt einzurichten, einschließlich der automatischen Erstellung einer jest.config.ts|js-Datei.

Aktualisieren Sie Ihre Konfigurationsdatei, um next/jest zu verwenden. Dieser Transformer enthält alle notwendigen Konfigurationsoptionen, damit Jest mit Next.js funktioniert:

import type { Config } from 'jest'
import nextJest from 'next/jest.js'

const createJestConfig = nextJest({
  // Geben Sie den Pfad zu Ihrer Next.js-App an, um next.config.js und .env-Dateien in Ihrer Testumgebung zu laden
  dir: './',
})

// Fügen Sie benutzerdefinierte Konfigurationen hinzu, die an Jest übergeben werden sollen
const config: Config = {
  coverageProvider: 'v8',
  testEnvironment: 'jsdom',
  // Fügen Sie weitere Setup-Optionen vor jedem Testlauf hinzu
  // setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}

// createJestConfig wird auf diese Weise exportiert, um sicherzustellen, dass next/jest die Next.js-Konfiguration laden kann, die asynchron ist
export default createJestConfig(config)

Unter der Haube konfiguriert next/jest Jest automatisch für Sie, einschließlich:

  • Einrichten von transform mit dem Next.js Compiler.
  • Automatisches Mocken von Stylesheets (.css, .module.css und deren SCSS-Varianten), Bildimporten und next/font.
  • Laden von .env (und allen Varianten) in process.env.
  • Ignorieren von node_modules bei der Testauflösung und Transformation.
  • Ignorieren von .next bei der Testauflösung.
  • Laden von next.config.js für Flags, die SWC-Transformationen ermöglichen.

Gut zu wissen: Um Umgebungsvariablen direkt zu testen, laden Sie sie manuell in einem separaten Setup-Skript oder in Ihrer jest.config.ts-Datei. Weitere Informationen finden Sie unter Testumgebungsvariablen.

Optional: Umgang mit absoluten Imports und Modulpfad-Aliasen

Wenn Ihr Projekt Modulpfad-Aliasen verwendet, müssen Sie Jest so konfigurieren, dass die Imports aufgelöst werden, indem Sie die Pfadoptionen in der jsconfig.json-Datei mit der moduleNameMapper-Option in der jest.config.js-Datei abgleichen. Zum Beispiel:

tsconfig.json oder jsconfig.json
{
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "bundler",
    "baseUrl": "./",
    "paths": {
      "@/components/*": ["components/*"]
    }
  }
}
jest.config.js
moduleNameMapper: {
  // ...
  '^@/components/(.*)$': '<rootDir>/components/$1',
}

Optional: Erweitern Sie Jest mit benutzerdefinierten Matchern

@testing-library/jest-dom enthält eine Reihe praktischer benutzerdefinierter Matcher wie .toBeInTheDocument(), die das Schreiben von Tests erleichtern. Sie können die benutzerdefinierten Matcher für jeden Test importieren, indem Sie die folgende Option zur Jest-Konfigurationsdatei hinzufügen:

setupFilesAfterEnv: ['<rootDir>/jest.setup.ts']

Fügen Sie dann in jest.setup den folgenden Import hinzu:

import '@testing-library/jest-dom'

Gut zu wissen: extend-expect wurde in v6.0 entfernt. Wenn Sie also @testing-library/jest-dom vor Version 6 verwenden, müssen Sie stattdessen @testing-library/jest-dom/extend-expect importieren.

Wenn Sie vor jedem Test weitere Setup-Optionen hinzufügen müssen, können Sie diese in der oben genannten jest.setup-Datei hinzufügen.

Fügen Sie ein Test-Skript zu package.json hinzu

Fügen Sie schließlich ein Jest-test-Skript zu Ihrer package.json-Datei hinzu:

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "test": "jest",
    "test:watch": "jest --watch"
  }
}

jest --watch führt Tests erneut aus, wenn eine Datei geändert wird. Weitere Jest-CLI-Optionen finden Sie in den Jest-Dokumenten.

Erstellen Ihres ersten Tests

Ihr Projekt ist jetzt bereit für Tests. Erstellen Sie einen Ordner namens __tests__ im Stammverzeichnis Ihres Projekts.

Zum Beispiel können wir einen Test hinzufügen, um zu überprüfen, ob die <Page />-Komponente erfolgreich eine Überschrift rendert:

app/page.js
import Link from 'next/link'

export default function Page() {
  return (
    <div>
      <h1>Home</h1>
      <Link href="/about">About</Link>
    </div>
  )
}
__tests__/page.test.jsx
import '@testing-library/jest-dom'
import { render, screen } from '@testing-library/react'
import Page from '../app/page'

describe('Page', () => {
  it('renders a heading', () => {
    render(<Page />)

    const heading = screen.getByRole('heading', { level: 1 })

    expect(heading).toBeInTheDocument()
  })
})

Optional können Sie einen Snapshot-Test hinzufügen, um unerwartete Änderungen in Ihrer Komponente zu verfolgen:

__tests__/snapshot.js
import { render } from '@testing-library/react'
import Page from '../app/page'

it('renders homepage unchanged', () => {
  const { container } = render(<Page />)
  expect(container).toMatchSnapshot()
})

Ausführen Ihrer Tests

Führen Sie dann den folgenden Befehl aus, um Ihre Tests auszuführen:

Terminal
npm run test
# oder
yarn test
# oder
pnpm test

Zusätzliche Ressourcen

Für weiterführende Lektüre können Ihnen diese Ressourcen helfen:

On this page