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ürasync
-Komponenten.
Schnellstart
Sie können create-next-app
mit dem Next.js with-jest-Beispiel verwenden, um schnell loszulegen:
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:
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:
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)
const nextJest = require('next/jest')
/** @type {import('jest').Config} */
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 = {
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
module.exports = 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 undnext/font
. - Laden von
.env
(und allen Varianten) inprocess.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.
Jest mit Babel einrichten
Wenn Sie den Next.js Compiler nicht verwenden und stattdessen Babel nutzen, müssen Sie Jest manuell konfigurieren und zusätzlich zu den oben genannten Paketen babel-jest
und identity-obj-proxy
installieren.
Hier sind die empfohlenen Optionen zur Konfiguration von Jest für Next.js:
module.exports = {
collectCoverage: true,
// Auf Node 14.x bietet der Coverage-Provider v8 eine gute Geschwindigkeit und mehr oder weniger gute Berichte
coverageProvider: 'v8',
collectCoverageFrom: [
'**/*.{js,jsx,ts,tsx}',
'!**/*.d.ts',
'!**/node_modules/**',
'!<rootDir>/out/**',
'!<rootDir>/.next/**',
'!<rootDir>/*.config.js',
'!<rootDir>/coverage/**',
],
moduleNameMapper: {
// Umgang mit CSS-Imports (mit CSS-Modulen)
// https://jestjs.io/docs/webpack#mocking-css-modules
'^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
// Umgang mit CSS-Imports (ohne CSS-Modulen)
'^.+\\.(css|sass|scss)$': '<rootDir>/__mocks__/styleMock.js',
// Umgang mit Bildimporten
// https://jestjs.io/docs/webpack#handling-static-assets
'^.+\\.(png|jpg|jpeg|gif|webp|avif|ico|bmp|svg)$': `<rootDir>/__mocks__/fileMock.js`,
// Umgang mit Modul-Aliasen
'^@/components/(.*)$': '<rootDir>/components/$1',
// Umgang mit @next/font
'@next/font/(.*)': `<rootDir>/__mocks__/nextFontMock.js`,
// Umgang mit next/font
'next/font/(.*)': `<rootDir>/__mocks__/nextFontMock.js`,
// Deaktivierung von server-only
'server-only': `<rootDir>/__mocks__/empty.js`,
},
// Fügen Sie weitere Setup-Optionen vor jedem Testlauf hinzu
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/.next/'],
testEnvironment: 'jsdom',
transform: {
// Verwenden Sie babel-jest, um Tests mit dem next/babel-Preset zu transpilieren
// https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object
'^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }],
},
transformIgnorePatterns: [
'/node_modules/',
'^.+\\.module\\.(css|sass|scss)$',
],
}
Weitere Informationen zu jeder Konfigurationsoption finden Sie in den Jest-Dokumenten. Wir empfehlen auch, die next/jest
-Konfiguration zu überprüfen, um zu sehen, wie Next.js Jest konfiguriert.
Umgang mit Stylesheets und Bildimporten
Stylesheets und Bilder werden in den Tests nicht verwendet, aber das Importieren kann zu Fehlern führen, daher müssen sie gemockt werden.
Erstellen Sie die in der obigen Konfiguration referenzierten Mock-Dateien - fileMock.js
und styleMock.js
- in einem __mocks__
-Verzeichnis:
module.exports = 'test-file-stub'
module.exports = {}
Weitere Informationen zum Umgang mit statischen Assets finden Sie in den Jest-Dokumenten.
Umgang mit Schriftarten
Um Schriftarten zu handhaben, erstellen Sie die Datei nextFontMock.js
im __mocks__
-Verzeichnis und fügen Sie die folgende Konfiguration hinzu:
module.exports = new Proxy(
{},
{
get: function getter() {
return () => ({
className: 'className',
variable: 'variable',
style: { fontFamily: 'fontFamily' },
})
},
}
)
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:
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler",
"baseUrl": "./",
"paths": {
"@/components/*": ["components/*"]
}
}
}
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']
setupFilesAfterEnv: ['<rootDir>/jest.setup.js']
Fügen Sie dann in jest.setup
den folgenden Import hinzu:
import '@testing-library/jest-dom'
import '@testing-library/jest-dom'
Gut zu wissen:
extend-expect
wurde inv6.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:
{
"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 <Home />
-Komponente erfolgreich eine Überschrift rendert:
export default function Home() {
return <h1>Home</h1>
}
import '@testing-library/jest-dom'
import { render, screen } from '@testing-library/react'
import Home from '../pages/index'
describe('Home', () => {
it('renders a heading', () => {
render(<Home />)
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:
import { render } from '@testing-library/react'
import Home from '../pages/index'
it('renders homepage unchanged', () => {
const { container } = render(<Home />)
expect(container).toMatchSnapshot()
})
Gut zu wissen: Testdateien sollten nicht im Pages-Router enthalten sein, da alle Dateien im Pages-Router als Routen betrachtet werden.
Ausführen Ihrer Tests
Führen Sie dann den folgenden Befehl aus, um Ihre Tests auszuführen:
npm run test
# oder
yarn test
# oder
pnpm test
Zusätzliche Ressourcen
Für weiterführende Lektüre können Ihnen diese Ressourcen helfen:
- Next.js mit Jest-Beispiel
- Jest-Dokumente
- React Testing Library-Dokumente
- Testing Playground - verwenden Sie gute Testpraktiken, um Elemente abzugleichen.