mcpField
T
testing-next-stack

testing-next-stack

github.com/hopeoverture测试与质量743 次安装50 周前更新
代码仓库

关于 testing-next-stack

为 Next.js 应用搭建测试基础设施的技能,适用于新建或规范化测试流程的团队。它通过生成配置、工具和示例,覆盖单元、组件、端到端及无障碍测试。

主要功能

  1. 01Vitest 单元测试配置
  2. 02React Testing Library 组件测试设置
  3. 03Playwright 端到端测试配置
  4. 04axe-core 无障碍检查
  5. 05测试工具与示例文件

适用场景

  1. 01为新的 Next.js 项目搭建测试
  2. 02将项目从 Jest 迁移至 Vitest
  3. 03添加 Playwright 端到端及无障碍测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hopeoverture/worldbuilding-app-skills --skill testing-next-stack

安装后在 Claude Code 中输入/testing-next-stack确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
playwright.config.ts
test-setup.ts
vitest.config.ts
assets/examples/
component-test.tsx
e2e-test.ts
unit-test.ts
references/
a11y-testing.md
scripts/
generate_test_deps.py

详细介绍

测试 Next Stack

使用现代测试工具,为 Next.js 应用搭建完整的测试基础设施。

概览

要为 Next.js 应用创建全面的测试配置,请使用此技能生成:

  • 用于快速单元测试的 Vitest 配置
  • 用于组件测试的 React Testing Library 设置
  • 用于 E2E 测试的 Playwright 配置
  • 使用 axe-core 进行无障碍测试
  • 测试工具和辅助函数
  • 展示最佳实践的示例测试文件

适用场景

在以下情况下使用此技能:

  • 启动一个需要测试基础设施的新 Next.js 项目
  • 从 Jest 迁移到 Vitest
  • 使用 Playwright 添加 E2E 测试
  • 实施无障碍测试要求
  • 为 worldbuilding 应用功能(实体、关系、时间线)创建测试工具
  • 在多个项目中统一测试模式

设置流程

1. 分析项目结构

若要了解项目布局,请检查:

  • Package.json 中现有的依赖项
  • Next.js 版本和配置
  • TypeScript 或 JavaScript 设置
  • 现有测试基础设施
  • 组件架构
2. 安装依赖项

使用 scripts/generate_test_deps.py 生成 package.json 中的新增内容:

python scripts/generate_test_deps.py --nextjs-version <version> --typescript

安装所需的软件包:

  • vitest - 快速单元测试运行器
  • @testing-library/react - 组件测试工具
  • @testing-library/jest-dom - 自定义匹配器
  • @testing-library/user-event - 用户交互模拟
  • @playwright/test - E2E 测试框架
  • @axe-core/playwright - 无障碍测试
  • @vitejs/plugin-react - Vite React 插件
  • jsdom - Vitest 的 DOM 实现
3. 生成配置文件

使用 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. 创建测试工具

在 test/utils/ 中生成工具函数:

渲染工具(test/utils/render.tsx):

  • 包装各类 Provider 的自定义渲染函数
  • Context Provider(身份验证、主题、数据)
  • Next.js 路由器模拟
  • 为 React Query 设置 Query 客户端

模拟工厂(test/utils/factories.ts):

  • 实体模拟数据生成器
  • 关系模拟数据
  • 用户模拟数据
  • API 响应模拟

测试辅助函数(test/utils/helpers.ts):

  • 异步测试工具
  • DOM 查询快捷方式
  • 无障碍测试辅助函数
  • 自定义匹配器
5. 生成示例测试

创建展示测试模式的示例测试文件:

单元测试示例(test/unit/example.test.ts):

  • 使用 assets/examples/unit-test.ts 中的模板
  • 演示纯函数测试
  • 展示异步函数测试
  • 包含边缘案例覆盖

组件测试示例(test/component/example.test.tsx):

  • 使用 assets/examples/component-test.tsx 中的模板
  • 演示渲染和断言
  • 展示用户交互测试
  • 包含使用 axe 进行的无障碍检查

E2E 测试示例(test/e2e/example.spec.ts):

  • 使用 assets/examples/e2e-test.ts 中的模板
  • 演示用户流程测试
  • 展示身份验证流程
  • 包含无障碍扫描
6. 更新软件包脚本

将测试脚本添加到 package.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"
  }
}

测试模式

使用 Vitest 进行单元测试

若要测试工具函数和业务逻辑:

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)
  })
})
使用 RTL 进行组件测试

若要测试 React 组件:

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)
  })
})
使用 Playwright 进行 E2E 测试

若要测试完整的用户流程:

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)
})

无障碍测试

组件级无障碍测试

要在组件测试中添加无障碍断言:

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()
})
端到端无障碍扫描

要扫描整个页面,检查无障碍问题:

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)
})

覆盖率配置

要生成代码覆盖率报告,请在 vitest.config.ts 中配置 Vitest 覆盖率:

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
      }
    }
  }
})

资源

请参考以下资源,了解详细信息:

  • 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/ - 测试文件示例

后续步骤

搭建好测试基础设施后:

  1. 运行 npm install 安装依赖项
  2. 执行 npm test 验证 Vitest 设置
  3. 执行 npm run test:e2e 验证 Playwright 设置
  4. 检查并自定义配置文件
  5. 为现有组件和功能添加测试
  6. 配置包含测试执行的 CI/CD 流水线
  7. 在 CI 中设置覆盖率报告
  8. 为团队编写测试指南文档

评论

支持 Markdown