mcpField
V
vitest-testing

vitest-testing

github.com/oakoss测试与质量20217 次安装11 周前更新
代码仓库

关于 vitest-testing

面向使用 Vitest 的开发者,提供单元、组件、集成和 Hook 测试的实用指南。涵盖常用 API、测试库模式、配置与 CLI 操作。

主要功能

  1. 01测试结构、断言与生命周期钩子
  2. 02函数、模块和方法模拟
  3. 03React 组件与 Hook 测试
  4. 04异步断言与快照
  5. 05CLI 筛选、并发与分片

适用场景

  1. 01为 Vite 项目编写单元测试
  2. 02用 React Testing Library 验证组件交互
  3. 03测试 TanStack Query、Router 或 Form 模式

安装

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

$npx skills add https://github.com/oakoss/agent-skills --skill vitest-testing

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

包含的文件

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

references/
advanced-patterns.md
cli-and-filtering.md
component-testing.md
configuration.md
fixtures-and-context.md
hook-testing.md
mocking.md
test-fundamentals.md
test-setup.md

详细介绍

Vitest 测试

概述

Vitest 是一个原生支持 Vite 的单元测试框架,与 Vite 共用配置和插件生态系统。它原生支持 ESM、支持测试热模块替换和并行执行,旨在实现快速运行。

适用场景: 单元测试、组件测试、集成测试、Hook 测试、源码内测试。使用 React Testing Library 测试 React 组件。测试 TanStack Query/Router/Form 模式。

不适用场景: 端到端测试(使用 Playwright)、视觉回归测试(使用 Percy/Chromatic)、负载测试(使用 k6)。

快速参考

模式API关键要点
测试结构describe('suite', () => {})组织相关测试
单个测试test('behavior', () => {}) or it()两者是别名
参数化测试test.each([...])('name', (arg) => {})使用不同输入运行同一测试
并发测试test.concurrent('name', async () => {})并行运行测试
跳过测试test.skip('name', () => {}) or skipIf(cond)有条件地跳过测试
仅运行此测试test.only('name', () => {})运行特定测试以进行调试
断言expect(value).toBe(expected)比较基本类型值
深度相等expect(obj).toEqual(expected)比较对象/数组
异步断言await expect(promise).resolves.toBe(value)测试 Promise 是否成功兑现
每个测试前beforeEach(() => {})在每个测试前进行设置
每个测试后afterEach(() => {})在每个测试后进行清理
模拟函数vi.fn()创建间谍函数
模拟模块vi.mock('./module')替换整个模块
监视方法vi.spyOn(obj, 'method')跟踪对现有方法的调用
清除模拟vi.clearAllMocks()清除调用历史
虚假计时器vi.useFakeTimers()控制 setTimeout/setInterval
渲染组件render(<Component />)挂载 React 组件以进行测试
按角色查询screen.getByRole('button')按无障碍角色查找元素
用户交互await user.click(element)模拟用户事件
等待变化await waitFor(() => expect(...))等待异步变化
查找异步元素await screen.findByText('text')合并查询与等待
渲染 HookrenderHook(() => useHook())测试自定义 Hook
更新 Hook 属性rerender(newProps)使用新属性重新渲染 Hook
快照expect(value).toMatchSnapshot()与已保存的快照进行比较
内联快照expect(value).toMatchInlineSnapshot()将快照存储在测试文件中
CLI 运行一次vitest run单次运行,不启用监视
运行已更改的测试vitest --changed运行受 git 变更影响的测试
按名称筛选vitest -t "pattern"搜索测试名称
软断言expect.soft(value).toBe(x)失败时继续执行并收集所有结果
轮询断言await expect.poll(() => val).toBe(x)重试直到通过
测试夹具const test = base.extend<F>({...})通过 test.extend 复用设置
提升的模拟vi.hoisted(() => ({ fn: vi.fn() }))为 vi.mock 工厂提供变量
分片测试vitest --shard 1/3在 CI 工作器之间拆分
标签test('name', { tags: ['slow'] }, ...)使用 --tags-filter 筛选
替换全局对象vi.stubGlobal('fetch', vi.fn())干净地替换全局对象

常见错误

错误正确做法
对异步内容使用 getBy对异步内容使用 findBy 或 waitFor
测试实现细节测试行为和公共 API
首选 getByTestId优先使用 getByRole、getByLabelText、getByText
忘记调用 userEvent.setup()始终先调用 const user = userEvent.setup()
在测试间共享状态使用 beforeEach 重置状态或创建新实例
未清理模拟在 afterEach 中使用 vi.clearAllMocks()
模拟过多只模拟外部依赖和 API
未在测试中禁用重试在 TanStack Query 测试中设置 retry: false
对异步操作立即进行断言使用 await waitFor() 或 findBy 查询
在 render 中创建 QueryClient在包装器中创建一次,或使用 useState
测试库代码信任库,测试你的使用方式
未等待用户事件所有 user.* 方法都会返回 Promise
手动使用 actuserEvent 和 Testing Library 会处理此事
内联 select 未进行记忆化提取为稳定函数,以供 TanStack Query 使用
在 vi.mock 工厂中使用变量使用 vi.hoisted() 声明模拟变量
使用单个 expect 进行多项检查使用 expect.soft() 收集所有失败
在测试中使用 setTimeout 等待异步操作使用 expect.poll() 或 vi.waitFor()
为可复用设置手动编写 beforeEach使用 test.extend fixture 实现可组合设置

委派

  • 测试发现:查找未覆盖的代码路径时,使用 Explore Agent
  • 覆盖率分析:进行完整覆盖率审查时,使用 Task Agent
  • E2E 测试:如果有 playwright 技能,将 E2E 测试委派给它
  • 代码审查:编写测试后,委派给 code-reviewer Agent

参考资料

评论

支持 Markdown