Next.js 测试 🧪
🎯 概述
测试是保证代码质量的关键。Next.js 支持多种测试方案,包括单元测试、集成测试和端到端测试。
📦 Jest + React Testing Library
安装
bash
npm install -D jest @testing-library/react @testing-library/jest-dom jest-environment-jsdom配置
js
// jest.config.js
const nextJest = require('next/jest')
const createJestConfig = nextJest({
dir: './',
})
const customJestConfig = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testEnvironment: 'jest-environment-jsdom',
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/$1',
},
}
module.exports = createJestConfig(customJestConfig)
// jest.setup.js
import '@testing-library/jest-dom'组件测试
tsx
// components/Button.test.tsx
import { render, screen, fireEvent } from '@testing-library/react'
import Button from './Button'
describe('Button', () => {
it('renders button text', () => {
render(<Button>Click me</Button>)
expect(screen.getByText('Click me')).toBeInTheDocument()
})
it('calls onClick when clicked', () => {
const handleClick = jest.fn()
render(<Button onClick={handleClick}>Click me</Button>)
fireEvent.click(screen.getByText('Click me'))
expect(handleClick).toHaveBeenCalledTimes(1)
})
})🚀 Playwright (E2E)
安装
bash
npm install -D @playwright/test
npx playwright install配置
ts
// playwright.config.ts
import { defineConfig } from '@playwright/test'
export default defineConfig({
testDir: './e2e',
use: {
baseURL: 'http://localhost:3000',
},
webServer: {
command: 'npm run dev',
port: 3000,
},
})E2E 测试
ts
// e2e/home.spec.ts
import { test, expect } from '@playwright/test'
test('home page', async ({ page }) => {
await page.goto('/')
await expect(page.getByRole('heading', { name: '欢迎' })).toBeVisible()
})
test('navigation', async ({ page }) => {
await page.goto('/')
await page.click('text=关于')
await expect(page).toHaveURL('/about')
})📝 API 测试
tsx
// app/api/users/route.test.ts
import { GET, POST } from './route'
describe('/api/users', () => {
it('GET returns users', async () => {
const response = await GET()
const data = await response.json()
expect(Array.isArray(data)).toBe(true)
})
it('POST creates user', async () => {
const request = new Request('http://localhost:3000/api/users', {
method: 'POST',
body: JSON.stringify({ name: '张三', email: 'zhang@example.com' })
})
const response = await POST(request)
const data = await response.json()
expect(data.name).toBe('张三')
})
})📚 最佳实践
1. 测试覆盖率
json
// package.json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
}
}2. Mock 数据
tsx
// __mocks__/api.ts
export const mockUser = {
id: '1',
name: '张三',
email: 'zhang@example.com'
}
// components/UserProfile.test.tsx
jest.mock('@/lib/api')
import { mockUser } from '@/__mocks__/api'
test('displays user info', async () => {
render(<UserProfile userId="1" />)
expect(await screen.findByText(mockUser.name)).toBeInTheDocument()
})3. 快照测试
tsx
import { render } from '@testing-library/react'
import Component from './Component'
test('matches snapshot', () => {
const { container } = render(<Component />)
expect(container).toMatchSnapshot()
})🔗 相关资源
下一步:学习 Next.js 性能优化。