testing-next-stack

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Testing Next Stack

Next.js 全栈测试方案

Scaffold complete testing infrastructure for Next.js applications with modern testing tools.
使用现代化测试工具为Next.js应用搭建完整的测试基础设施。

Overview

概述

To create a comprehensive testing setup for Next.js applications, use this skill to generate:
  • Vitest configuration for fast unit tests
  • React Testing Library setup for component testing
  • Playwright configuration for E2E testing
  • Accessibility testing with axe-core
  • Test utilities and helpers
  • Example test files demonstrating best practices
要为Next.js应用创建全面的测试环境,可使用本技能生成以下内容:
  • 用于快速单元测试的Vitest配置
  • 用于组件测试的React Testing Library环境搭建
  • 用于端到端测试的Playwright配置
  • 基于axe-core的无障碍测试
  • 测试工具与辅助函数
  • 展示最佳实践的示例测试文件

When to Use

适用场景

Use this skill when:
  • Starting a new Next.js project requiring test infrastructure
  • Migrating from Jest to Vitest
  • Adding E2E testing with Playwright
  • Implementing accessibility testing requirements
  • Creating test utilities for worldbuilding app features (entities, relationships, timelines)
  • Standardizing testing patterns across projects
在以下场景中使用本技能:
  • 启动需要测试基础设施的全新Next.js项目
  • 从Jest迁移至Vitest
  • 添加基于Playwright的端到端测试
  • 落实无障碍测试需求
  • 为世界观构建类应用功能(实体、关系、时间线)创建测试工具
  • 跨项目统一测试模式

Setup Process

搭建流程

1. Analyze Project Structure

1. 分析项目结构

To understand the project layout, examine:
  • Package.json for existing dependencies
  • Next.js version and configuration
  • TypeScript or JavaScript setup
  • Existing testing infrastructure
  • Component architecture
为了解项目布局,需检查以下内容:
  • 现有依赖的package.json
  • Next.js版本与配置
  • TypeScript或JavaScript环境
  • 已有的测试基础设施
  • 组件架构

2. Install Dependencies

2. 安装依赖

Generate package.json additions using
scripts/generate_test_deps.py
:
bash
python scripts/generate_test_deps.py --nextjs-version <version> --typescript
Install required packages:
  • vitest
    - Fast unit test runner
  • @testing-library/react
    - Component testing utilities
  • @testing-library/jest-dom
    - Custom matchers
  • @testing-library/user-event
    - User interaction simulation
  • @playwright/test
    - E2E testing framework
  • @axe-core/playwright
    - Accessibility testing
  • @vitejs/plugin-react
    - Vite React plugin
  • jsdom
    - DOM implementation for Vitest
使用
scripts/generate_test_deps.py
生成package.json依赖项:
bash
python scripts/generate_test_deps.py --nextjs-version <version> --typescript
安装所需包:
  • vitest
    - 快速单元测试运行器
  • @testing-library/react
    - 组件测试工具
  • @testing-library/jest-dom
    - 自定义断言匹配器
  • @testing-library/user-event
    - 用户交互模拟工具
  • @playwright/test
    - 端到端测试框架
  • @axe-core/playwright
    - 无障碍测试工具
  • @vitejs/plugin-react
    - Vite React插件
  • jsdom
    - Vitest用DOM实现

3. Generate Configuration Files

3. 生成配置文件

Create configuration files using templates from
assets/
:
Vitest Configuration (
vitest.config.ts
):
  • Use template from
    assets/vitest.config.ts
  • Configure path aliases matching Next.js
  • Set up test environment (jsdom)
  • Configure coverage reporting
Playwright Configuration (
playwright.config.ts
):
  • Use template from
    assets/playwright.config.ts
  • Configure browsers (chromium, firefox, webkit)
  • Set baseURL for development server
  • Configure screenshot and video capture
  • Set up test artifacts directory
Test Setup (
test/setup.ts
):
  • Use template from
    assets/test-setup.ts
  • Import @testing-library/jest-dom
  • Configure global test utilities
  • Set up mock implementations
使用
assets/
中的模板创建配置文件:
Vitest配置 (
vitest.config.ts
):
  • 使用
    assets/vitest.config.ts
    中的模板
  • 配置与Next.js匹配的路径别名
  • 设置测试环境(jsdom)
  • 配置覆盖率报告
Playwright配置 (
playwright.config.ts
):
  • 使用
    assets/playwright.config.ts
    中的模板
  • 配置浏览器(chromium、firefox、webkit)
  • 设置开发服务器的baseURL
  • 配置截图与视频捕获
  • 设置测试产物目录
测试初始化 (
test/setup.ts
):
  • 使用
    assets/test-setup.ts
    中的模板
  • 导入@testing-library/jest-dom
  • 配置全局测试工具
  • 设置模拟实现

4. Create Test Utilities

4. 创建测试工具

Generate utility functions in
test/utils/
:
Render Utilities (
test/utils/render.tsx
):
  • Custom render function wrapping providers
  • Context providers (auth, theme, data)
  • Router mocking for Next.js
  • Query client setup for React Query
Mock Factories (
test/utils/factories.ts
):
  • Entity mock data generators
  • Relationship mock data
  • User mock data
  • API response mocks
Test Helpers (
test/utils/helpers.ts
):
  • Async test utilities
  • DOM query shortcuts
  • Accessibility test helpers
  • Custom matchers
test/utils/
中生成工具函数:
渲染工具 (
test/utils/render.tsx
):
  • 包装Provider的自定义渲染函数
  • 上下文Provider(权限、主题、数据)
  • Next.js路由模拟
  • React Query查询客户端设置
模拟工厂 (
test/utils/factories.ts
):
  • 实体模拟数据生成器
  • 关系模拟数据
  • 用户模拟数据
  • API响应模拟
测试辅助函数 (
test/utils/helpers.ts
):
  • 异步测试工具
  • DOM查询快捷方式
  • 无障碍测试辅助函数
  • 自定义匹配器

5. Generate Example Tests

5. 生成示例测试

Create example test files demonstrating patterns:
Unit Test Example (
test/unit/example.test.ts
):
  • Use template from
    assets/examples/unit-test.ts
  • Demonstrate pure function testing
  • Show async function testing
  • Include edge case coverage
Component Test Example (
test/component/example.test.tsx
):
  • Use template from
    assets/examples/component-test.tsx
  • Demonstrate rendering and assertions
  • Show user interaction testing
  • Include accessibility checks with axe
E2E Test Example (
test/e2e/example.spec.ts
):
  • Use template from
    assets/examples/e2e-test.ts
  • Demonstrate user flow testing
  • Show authentication flows
  • Include accessibility scanning
创建展示测试模式的示例文件:
单元测试示例 (
test/unit/example.test.ts
):
  • 使用
    assets/examples/unit-test.ts
    中的模板
  • 演示纯函数测试
  • 展示异步函数测试
  • 包含边界场景覆盖
组件测试示例 (
test/component/example.test.tsx
):
  • 使用
    assets/examples/component-test.tsx
    中的模板
  • 演示渲染与断言
  • 展示用户交互测试
  • 包含基于axe的无障碍检查
端到端测试示例 (
test/e2e/example.spec.ts
):
  • 使用
    assets/examples/e2e-test.ts
    中的模板
  • 演示用户流程测试
  • 展示认证流程测试
  • 包含无障碍扫描

6. Update Package Scripts

6. 更新包脚本

Add test scripts to package.json:
json
{
  "scripts": {
    "test": "vitest",
    "test:ui": "vitest --ui",
    "test:coverage": "vitest --coverage",
    "test:e2e": "playwright test",
    "test:e2e:ui": "playwright test --ui",
    "test:e2e:debug": "playwright test --debug"
  }
}
在package.json中添加测试脚本:
json
{
  "scripts": {
    "test": "vitest",
    "test:ui": "vitest --ui",
    "test:coverage": "vitest --coverage",
    "test:e2e": "playwright test",
    "test:e2e:ui": "playwright test --ui",
    "test:e2e:debug": "playwright test --debug"
  }
}

Test Patterns

测试模式

Unit Testing with Vitest

基于Vitest的单元测试

To test utility functions and business logic:
typescript
import { describe, it, expect } from 'vitest'
import { validateEntityRelationship } from '@/lib/validation'

describe('validateEntityRelationship', () => {
  it('validates valid relationship', () => {
    const result = validateEntityRelationship({
      sourceId: '1',
      targetId: '2',
      type: 'BELONGS_TO'
    })
    expect(result.isValid).toBe(true)
  })

  it('rejects self-referential relationship', () => {
    const result = validateEntityRelationship({
      sourceId: '1',
      targetId: '1',
      type: 'BELONGS_TO'
    })
    expect(result.isValid).toBe(false)
  })
})
测试工具函数与业务逻辑:
typescript
import { describe, it, expect } from 'vitest'
import { validateEntityRelationship } from '@/lib/validation'

describe('validateEntityRelationship', () => {
  it('validates valid relationship', () => {
    const result = validateEntityRelationship({
      sourceId: '1',
      targetId: '2',
      type: 'BELONGS_TO'
    })
    expect(result.isValid).toBe(true)
  })

  it('rejects self-referential relationship', () => {
    const result = validateEntityRelationship({
      sourceId: '1',
      targetId: '1',
      type: 'BELONGS_TO'
    })
    expect(result.isValid).toBe(false)
  })
})

Component Testing with RTL

基于RTL的组件测试

To test React components:
typescript
import { render, screen } from '@/test/utils/render'
import { userEvent } from '@testing-library/user-event'
import { axe } from '@axe-core/playwright'
import EntityCard from '@/components/EntityCard'

describe('EntityCard', () => {
  it('renders entity information', () => {
    render(<EntityCard entity={mockEntity} />)
    expect(screen.getByText(mockEntity.name)).toBeInTheDocument()
  })

  it('handles edit action', async () => {
    const onEdit = vi.fn()
    render(<EntityCard entity={mockEntity} onEdit={onEdit} />)

    await userEvent.click(screen.getByRole('button', { name: /edit/i }))
    expect(onEdit).toHaveBeenCalledWith(mockEntity.id)
  })

  it('has no accessibility violations', async () => {
    const { container } = render(<EntityCard entity={mockEntity} />)
    const results = await axe(container)
    expect(results.violations).toHaveLength(0)
  })
})
测试React组件:
typescript
import { render, screen } from '@/test/utils/render'
import { userEvent } from '@testing-library/user-event'
import { axe } from '@axe-core/playwright'
import EntityCard from '@/components/EntityCard'

describe('EntityCard', () => {
  it('renders entity information', () => {
    render(<EntityCard entity={mockEntity} />)
    expect(screen.getByText(mockEntity.name)).toBeInTheDocument()
  })

  it('handles edit action', async () => {
    const onEdit = vi.fn()
    render(<EntityCard entity={mockEntity} onEdit={onEdit} />)

    await userEvent.click(screen.getByRole('button', { name: /edit/i }))
    expect(onEdit).toHaveBeenCalledWith(mockEntity.id)
  })

  it('has no accessibility violations', async () => {
    const { container } = render(<EntityCard entity={mockEntity} />)
    const results = await axe(container)
    expect(results.violations).toHaveLength(0)
  })
})

E2E Testing with Playwright

基于Playwright的端到端测试

To test complete user flows:
typescript
import { test, expect } from '@playwright/test'
import { injectAxe, checkA11y } from '@axe-core/playwright'

test('user creates new entity', async ({ page }) => {
  await page.goto('/entities')

  // Inject axe for accessibility testing
  await injectAxe(page)

  // Navigate to create form
  await page.getByRole('button', { name: /create entity/i }).click()

  // Fill form
  await page.getByLabel(/name/i).fill('New Character')
  await page.getByLabel(/type/i).selectOption('character')
  await page.getByLabel(/description/i).fill('A mysterious traveler')

  // Submit
  await page.getByRole('button', { name: /save/i }).click()

  // Verify success
  await expect(page.getByText('New Character')).toBeVisible()

  // Check accessibility
  await checkA11y(page)
})
测试完整用户流程:
typescript
import { test, expect } from '@playwright/test'
import { injectAxe, checkA11y } from '@axe-core/playwright'

test('user creates new entity', async ({ page }) => {
  await page.goto('/entities')

  // Inject axe for accessibility testing
  await injectAxe(page)

  // Navigate to create form
  await page.getByRole('button', { name: /create entity/i }).click()

  // Fill form
  await page.getByLabel(/name/i).fill('New Character')
  await page.getByLabel(/type/i).selectOption('character')
  await page.getByLabel(/description/i).fill('A mysterious traveler')

  // Submit
  await page.getByRole('button', { name: /save/i }).click()

  // Verify success
  await expect(page.getByText('New Character')).toBeVisible()

  // Check accessibility
  await checkA11y(page)
})

Accessibility Testing

无障碍测试

Component-Level A11y

组件级无障碍测试

To add accessibility assertions in component tests:
typescript
import { render } from '@/test/utils/render'
import { axe, toHaveNoViolations } from 'jest-axe'

expect.extend(toHaveNoViolations)

it('meets accessibility standards', async () => {
  const { container } = render(<MyComponent />)
  const results = await axe(container)
  expect(results).toHaveNoViolations()
})
在组件测试中添加无障碍断言:
typescript
import { render } from '@/test/utils/render'
import { axe, toHaveNoViolations } from 'jest-axe'

expect.extend(toHaveNoViolations)

it('meets accessibility standards', async () => {
  const { container } = render(<MyComponent />)
  const results = await axe(container)
  expect(results).toHaveNoViolations()
})

E2E A11y Scanning

端到端无障碍扫描

To scan entire pages for accessibility issues:
typescript
import { test } from '@playwright/test'
import { injectAxe, checkA11y, getViolations } from '@axe-core/playwright'

test('homepage accessibility', async ({ page }) => {
  await page.goto('/')
  await injectAxe(page)

  // Check entire page
  await checkA11y(page)

  // Or check specific element
  await checkA11y(page, '#main-content')

  // Or get violations for custom reporting
  const violations = await getViolations(page)
  expect(violations).toHaveLength(0)
})
扫描整页的无障碍问题:
typescript
import { test } from '@playwright/test'
import { injectAxe, checkA11y, getViolations } from '@axe-core/playwright'

test('homepage accessibility', async ({ page }) => {
  await page.goto('/')
  await injectAxe(page)

  // Check entire page
  await checkA11y(page)

  // Or check specific element
  await checkA11y(page, '#main-content')

  // Or get violations for custom reporting
  const violations = await getViolations(page)
  expect(violations).toHaveLength(0)
})

Coverage Configuration

覆盖率配置

To generate code coverage reports, configure Vitest coverage in
vitest.config.ts
:
typescript
export default defineConfig({
  test: {
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      exclude: [
        'node_modules/',
        'test/',
        '**/*.config.{ts,js}',
        '**/*.d.ts'
      ],
      thresholds: {
        lines: 80,
        functions: 80,
        branches: 80,
        statements: 80
      }
    }
  }
})
要生成代码覆盖率报告,在
vitest.config.ts
中配置Vitest覆盖率:
typescript
export default defineConfig({
  test: {
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      exclude: [
        'node_modules/',
        'test/',
        '**/*.config.{ts,js}',
        '**/*.d.ts'
      ],
      thresholds: {
        lines: 80,
        functions: 80,
        branches: 80,
        statements: 80
      }
    }
  }
})

Resources

参考资源

Consult the following resources for detailed information:
  • references/vitest-setup.md
    - Vitest configuration details
  • references/rtl-patterns.md
    - React Testing Library best practices
  • references/playwright-setup.md
    - Playwright configuration guide
  • references/a11y-testing.md
    - Accessibility testing guidelines
  • assets/vitest.config.ts
    - Vitest configuration template
  • assets/playwright.config.ts
    - Playwright configuration template
  • assets/test-setup.ts
    - Test setup template
  • assets/examples/
    - Example test files
如需详细信息,可查阅以下资源:
  • references/vitest-setup.md
    - Vitest配置细节
  • references/rtl-patterns.md
    - React Testing Library最佳实践
  • references/playwright-setup.md
    - Playwright配置指南
  • references/a11y-testing.md
    - 无障碍测试规范
  • assets/vitest.config.ts
    - Vitest配置模板
  • assets/playwright.config.ts
    - Playwright配置模板
  • assets/test-setup.ts
    - 测试初始化模板
  • assets/examples/
    - 示例测试文件

Next Steps

后续步骤

After scaffolding the testing infrastructure:
  1. Run
    npm install
    to install dependencies
  2. Execute
    npm test
    to verify Vitest setup
  3. Execute
    npm run test:e2e
    to verify Playwright setup
  4. Review and customize configuration files
  5. Add tests for existing components and features
  6. Configure CI/CD pipeline with test execution
  7. Set up coverage reporting in CI
  8. Document testing guidelines for team
完成测试基础设施搭建后:
  1. 运行
    npm install
    安装依赖
  2. 执行
    npm test
    验证Vitest环境
  3. 执行
    npm run test:e2e
    验证Playwright环境
  4. 审阅并自定义配置文件
  5. 为现有组件与功能添加测试
  6. 在CI/CD流水线中配置测试执行
  7. 在CI中设置覆盖率报告
  8. 为团队编写测试规范文档