Настройка Jest с Next.js
Jest и React Testing Library часто используются вместе для модульного тестирования (Unit Testing) и тестирования снимками (Snapshot Testing). Это руководство покажет вам, как настроить Jest с Next.js и написать первые тесты.
Полезно знать: Поскольку
asyncServer Components являются новинкой в экосистеме React, Jest в настоящее время их не поддерживает. Хотя вы все еще можете запускать модульные тесты для синхронных серверных и клиентских компонентов, мы рекомендуем использовать сквозные тесты (E2E tests) дляasyncкомпонентов.
Быстрый старт
Вы можете использовать create-next-app с примером Next.js with-jest, чтобы быстро начать работу:
npx create-next-app@latest --example with-jest with-jest-appРучная настройка
Начиная с версии Next.js 12, Next.js имеет встроенную конфигурацию для Jest.
Для настройки Jest установите jest и следующие пакеты как dev-зависимости:
npm install -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node @types/jest
# или
yarn add -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node @types/jest
# или
pnpm install -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node @types/jestСоздайте базовый файл конфигурации Jest, выполнив следующую команду:
npm init jest@latest
# или
yarn create jest@latest
# или
pnpm create jest@latestЭто запустит серию подсказок для настройки Jest в вашем проекте, включая автоматическое создание файла jest.config.ts|js.
Обновите файл конфигурации, чтобы использовать next/jest. Этот трансформер содержит все необходимые параметры конфигурации для работы Jest с Next.js:
import type { Config } from 'jest'
import nextJest from 'next/jest.js'
const createJestConfig = nextJest({
// Укажите путь к вашему приложению Next.js для загрузки next.config.js и .env файлов в тестовой среде
dir: './',
})
// Добавьте любую пользовательскую конфигурацию для передачи в Jest
const config: Config = {
coverageProvider: 'v8',
testEnvironment: 'jsdom',
// Добавьте дополнительные параметры настройки перед запуском каждого теста
// setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}
// createJestConfig экспортируется таким образом, чтобы next/jest мог загрузить асинхронную конфигурацию Next.js
export default createJestConfig(config)const nextJest = require('next/jest')
/** @type {import('jest').Config} */
const createJestConfig = nextJest({
// Укажите путь к вашему приложению Next.js для загрузки next.config.js и .env файлов в тестовой среде
dir: './',
})
// Добавьте любую пользовательскую конфигурацию для передачи в Jest
const config = {
coverageProvider: 'v8',
testEnvironment: 'jsdom',
// Добавьте дополнительные параметры настройки перед запуском каждого теста
// setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}
// createJestConfig экспортируется таким образом, чтобы next/jest мог загрузить асинхронную конфигурацию Next.js
module.exports = createJestConfig(config)Под капотом next/jest автоматически настраивает Jest для вас, включая:
- Настройку
transformс использованием Next.js Compiler. - Автоматическое мокирование таблиц стилей (
.css,.module.cssи их scss-вариантов), импортов изображений иnext/font. - Загрузку
.env(и всех вариантов) вprocess.env. - Игнорирование
node_modulesпри разрешении и трансформации тестов. - Игнорирование
.nextпри разрешении тестов. - Загрузку
next.config.jsдля флагов, включающих трансформации SWC.
Полезно знать: Для тестирования переменных окружения напрямую загружайте их вручную в отдельном скрипте настройки или в файле
jest.config.ts. Для получения дополнительной информации см. Test Environment Variables.
Опционально: Обработка абсолютных импортов и алиасов модулей
Если ваш проект использует алиасы модулей (Module Path Aliases), вам потребуется настроить Jest для разрешения импортов, сопоставив параметр paths в файле jsconfig.json с параметром moduleNameMapper в файле jest.config.js. Например:
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler",
"baseUrl": "./",
"paths": {
"@/components/*": ["components/*"]
}
}
}moduleNameMapper: {
// ...
'^@/components/(.*)$': '<rootDir>/components/$1',
}Опционально: Расширение Jest пользовательскими матчерами
@testing-library/jest-dom включает набор удобных пользовательских матчеров, таких как .toBeInTheDocument(), что упрощает написание тестов. Вы можете импортировать пользовательские матчеры для каждого теста, добавив следующий параметр в файл конфигурации Jest:
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts']setupFilesAfterEnv: ['<rootDir>/jest.setup.js']Затем внутри jest.setup добавьте следующий импорт:
import '@testing-library/jest-dom'import '@testing-library/jest-dom'Полезно знать:
extend-expectбыл удален вv6.0, поэтому если вы используете@testing-library/jest-domверсии ниже 6, вам нужно импортировать@testing-library/jest-dom/extend-expectвместо этого.
Если вам нужно добавить дополнительные параметры настройки перед каждым тестом, вы можете добавить их в файл jest.setup выше.
Добавление скрипта тестирования в package.json
Наконец, добавьте скрипт test для Jest в файл package.json:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "jest",
"test:watch": "jest --watch"
}
}jest --watch будет перезапускать тесты при изменении файла. Для получения дополнительных параметров CLI Jest обратитесь к документации Jest.
Создание первого теста
Ваш проект теперь готов к запуску тестов. Создайте папку __tests__ в корневой директории вашего проекта.
Например, мы можем добавить тест для проверки, успешно ли рендерится заголовок в компоненте <Page />:
import Link from 'next/link'
export default function Page() {
return (
<div>
<h1>Home</h1>
<Link href="/about">About</Link>
</div>
)
}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()
})
})Опционально добавьте тест снимков (snapshot test), чтобы отслеживать неожиданные изменения в вашем компоненте:
import { render } from '@testing-library/react'
import Page from '../app/page'
it('renders homepage unchanged', () => {
const { container } = render(<Page />)
expect(container).toMatchSnapshot()
})Запуск тестов
Затем выполните следующую команду для запуска тестов:
npm run test
# или
yarn test
# или
pnpm testДополнительные ресурсы
Для дальнейшего изучения могут быть полезны следующие ресурсы:
- Пример Next.js с Jest
- Документация Jest
- Документация React Testing Library
- Testing Playground - используйте лучшие практики тестирования для сопоставления элементов.