Vitest 简介 #

什么是 Vitest? #

Vitest 是由 Vite 和 Vue.js 团队开发的下一代测试框架,专为 Vite 构建的项目设计。它利用 Vite 的转换管道,提供极速的测试体验,原生支持 ESM、TypeScript、JSX 等现代前端技术栈。Vitest 的设计理念是"快如闪电,简单如斯",让测试成为一种享受而非负担。

核心定位 #

text
┌─────────────────────────────────────────────────────────────┐
│                         Vitest                               │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │
│  │  Vite 原生   │  │  极速执行    │  │  ESM 支持   │         │
│  └─────────────┘  └─────────────┘  └─────────────┘         │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │
│  │  Jest 兼容   │  │  TypeScript │  │  内置覆盖率  │         │
│  └─────────────┘  └─────────────┘  └─────────────┘         │
└─────────────────────────────────────────────────────────────┘

Vitest 的历史 #

发展历程 #

text
2022年 ─── Vitest 项目启动
    │
    │      Anthony Fu 发起
    │      Vite 生态原生测试方案
    │
2022年中 ─── 首个稳定版本
    │
    │      与 Vite 深度集成
    │      Jest 兼容 API
    │
2023年 ─── 快速迭代
    │
    │      浏览器模式
    │      性能测试
    │      快照测试增强
    │
2024年 ─── 生态成熟
    │
    │      VS Code 插件
    │      更多框架集成
    │      企业级采用
    │
至今   ─── 行业新标准
    │
    │      周下载量超过 200 万
    │      Vite 官方推荐
    │      主流框架默认选择

里程碑版本 #

版本 时间 重要特性
0.1.0 2022 初始发布,基础测试功能
0.10.0 2022 浏览器模式支持
0.20.0 2022 快照测试增强
0.30.0 2023 性能测试功能
1.0.0 2023 正式稳定版发布
1.2.0 2024 改进的 Watch 模式
2.0.0 2025 全新架构优化

为什么选择 Vitest? #

传统测试框架的痛点 #

在使用 Jest 等传统测试框架时,Vite 项目面临以下问题:

javascript
// 需要额外配置处理 ESM
// jest.config.js
module.exports = {
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
  },
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1',
  },
}

// 需要处理 Vite 特有的路径别名
// vite.config.ts 中的 resolve.alias
// 需要在 Jest 中重复配置

// 测试启动慢
// 需要重新编译整个项目

Vitest 的解决方案 #

javascript
// 无需额外配置
// vitest 自动读取 vite.config.ts

// 直接使用 Vite 的转换管道
// 测试代码和源代码使用相同的处理流程

// 极速启动
// 利用 Vite 的即时编译能力
// 毫秒级启动,秒级运行

// test/sum.test.ts
import { describe, it, expect } from 'vitest'
import { sum } from '../src/sum'

describe('sum', () => {
  it('adds 1 + 2 to equal 3', () => {
    expect(sum(1, 2)).toBe(3)
  })
})

Vitest 的核心特点 #

1. Vite 原生集成 #

与 Vite 共享配置和转换管道:

text
┌─────────────────────────────────────────────────────────────┐
│                      Vite 项目                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────────┐       ┌─────────────────┐            │
│   │  vite.config.ts │ ────> │    Vitest       │            │
│   │                 │       │                 │            │
│   │  - resolve      │       │  共享配置       │            │
│   │  - alias        │       │  共享插件       │            │
│   │  - plugins      │       │  共享转换       │            │
│   │  - define       │       │                 │            │
│   └─────────────────┘       └─────────────────┘            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2. 极速执行 #

利用 Vite 的即时编译能力:

bash
# Vitest 启动速度对比
Jest:    5-10 秒启动
Vitest:  < 1 秒启动

# 测试运行速度
Jest:    需要预编译
Vitest:  按需编译,即时执行

3. 原生 ESM 支持 #

无需配置即可使用 ES 模块:

javascript
// 直接使用 ESM
import { sum } from './sum.js'
import { config } from './config.js'

// 无需 moduleNameMapper
// 无需 transform 配置

4. Jest 兼容 API #

平滑迁移,学习成本低:

javascript
// 与 Jest 几乎相同的 API
describe('my suite', () => {
  beforeAll(() => {})
  beforeEach(() => {})
  
  test('my test', () => {
    expect(1 + 1).toBe(2)
  })
  
  afterEach(() => {})
  afterAll(() => {})
})

5. 内置 TypeScript / JSX 支持 #

开箱即用的类型支持:

typescript
// .ts 文件直接运行
import { describe, it, expect } from 'vitest'

interface User {
  id: number
  name: string
}

it('creates user', () => {
  const user: User = { id: 1, name: 'John' }
  expect(user.name).toBe('John')
})

6. 智能监听模式 #

高效的 Watch 模式:

bash
vitest --watch

# 只运行相关测试
# 智能依赖分析
# 即时反馈

Vitest 与其他测试框架对比 #

Vitest vs Jest #

特性 Vitest Jest
Vite 集成 ✅ 原生支持 ❌ 需要配置
ESM 支持 ✅ 原生支持 ⚠️ 需要配置
启动速度 ✅ 极快 ⚠️ 较慢
配置复杂度 ✅ 零配置 ⚠️ 需要配置
TypeScript ✅ 原生支持 ⚠️ 需要 ts-jest
生态系统 🔄 发展中 ✅ 成熟
学习曲线 ✅ 低 ⚠️ 中等

Vitest vs Mocha #

特性 Vitest Mocha
零配置 ✅ 开箱即用 ❌ 需要配置
断言库 ✅ 内置 ❌ 需要 chai
Mock 功能 ✅ 内置 ❌ 需要 sinon
代码覆盖率 ✅ 内置 ❌ 需要 nyc
Watch 模式 ✅ 智能 ⚠️ 基础

Vitest vs Ava #

特性 Vitest Ava
Vite 集成 ✅ 原生支持 ❌ 无
并行执行 ✅ 自动 ✅ 自动
快照测试 ✅ 支持 ✅ 支持
TypeScript ✅ 原生 ⚠️ 需配置

Vitest 的应用场景 #

1. Vite 项目测试 #

最适合使用 Vite 构建的项目:

javascript
// Vue 3 项目
import { mount } from '@vue/test-utils'
import MyComponent from './MyComponent.vue'

test('mounts component', () => {
  const wrapper = mount(MyComponent)
  expect(wrapper.html()).toContain('Hello')
})

2. React 项目测试 #

完美支持 React:

javascript
// React 项目
import { render, screen } from '@testing-library/react'
import App from './App'

test('renders app', () => {
  render(<App />)
  expect(screen.getByText('Hello')).toBeInTheDocument()
})

3. 组件库测试 #

测试 UI 组件库:

javascript
// 组件库测试
import { describe, it, expect } from 'vitest'
import Button from './Button'

describe('Button', () => {
  it('renders correctly', () => {
    // 测试渲染
  })
  
  it('handles click', () => {
    // 测试交互
  })
})

4. Node.js 后端测试 #

也可以测试 Node.js 项目:

javascript
// Node.js API 测试
import { describe, it, expect, vi } from 'vitest'
import { getUser } from './api'

describe('API', () => {
  it('fetches user', async () => {
    const user = await getUser(1)
    expect(user).toBeDefined()
  })
})

Vitest 的核心概念 #

测试结构 #

javascript
// 基本结构
describe('测试套件', () => {
  beforeAll(() => {
    // 所有测试之前执行一次
  })

  beforeEach(() => {
    // 每个测试之前执行
  })

  it('测试用例', () => {
    // 单个测试
  })

  test('另一个测试', () => {
    // test 是 it 的别名
  })

  afterEach(() => {
    // 每个测试之后执行
  })

  afterAll(() => {
    // 所有测试之后执行一次
  })
})

断言 #

javascript
import { expect } from 'vitest'

test('assertions', () => {
  // 基本断言
  expect(1 + 1).toBe(2)
  expect({ a: 1 }).toEqual({ a: 1 })
  expect(true).toBeTruthy()
  expect([1, 2, 3]).toContain(2)
  
  // 否定断言
  expect(null).not.toBeUndefined()
})

Mock #

javascript
import { vi, expect } from 'vitest'

// 函数 Mock
const mockFn = vi.fn()
mockFn('hello')
expect(mockFn).toHaveBeenCalledWith('hello')

// 模块 Mock
vi.mock('./api', () => ({
  fetchUser: vi.fn(() => Promise.resolve({ id: 1 }))
}))

Vitest 的设计哲学 #

1. 开发者体验优先 #

javascript
// 清晰的错误消息
// Error: expected 1 to be 2
// ❌ AssertionError: expected 1 to be 2
//   at Object.<anonymous> (sum.test.ts:5:10)

// 智能错误定位
// 直接跳转到源码位置

2. 约定优于配置 #

text
my-project/
├── src/
│   ├── sum.ts
│   └── sum.test.ts    # 自动识别 *.test.ts
├── test/              # 自动识别 test 目录
│   └── integration.test.ts
├── __tests__/         # 自动识别 __tests__ 目录
│   └── unit.test.ts
└── vite.config.ts     # 共享 Vite 配置

3. 性能至上 #

  • 即时编译,按需加载
  • 智能并行执行
  • 增量测试
  • 热更新

Vitest 的优势 #

1. 开发效率 #

text
传统流程:
编写代码 -> 等待编译 -> 运行测试 -> 等待结果
         (5-10秒)           (5-10秒)

Vitest 流程:
编写代码 -> 即时测试 -> 即时反馈
         (< 1秒)      (< 1秒)

2. 配置简化 #

javascript
// Jest 需要的配置
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'jsdom',
  moduleNameMapper: { ... },
  transform: { ... },
  setupFilesAfterEnv: [ ... ],
  // ... 更多配置
}

// Vitest 需要的配置
// vite.config.ts
export default defineConfig({
  // 通常不需要额外配置
  // Vitest 自动继承 Vite 配置
})

3. 现代技术栈 #

  • 原生支持 ESM
  • 原生支持 TypeScript
  • 原生支持 JSX
  • 原生支持 CSS Modules

Vitest 的局限性 #

已知限制 #

  1. 生态系统:相比 Jest,插件和工具较少
  2. 社区资源:文档和教程相对较少
  3. 兼容性:某些 Jest 特定功能不支持

解决方案 #

javascript
// 使用 Jest 兼容 API
// 大部分 Jest 代码可以直接迁移

// 使用社区插件
// vitest-when, vitest-mock-extended 等

// 参考官方文档
// https://vitest.dev

学习路径 #

text
入门阶段
├── 安装与配置
├── 编写第一个测试
├── 使用断言
└── 测试生命周期

进阶阶段
├── 异步测试
├── Mock 功能
├── 快照测试
└── DOM 测试

高级阶段
├── 自定义配置
├── 浏览器模式
├── 性能测试
└── 代码覆盖率

实战阶段
├── Vue 组件测试
├── React 组件测试
├── Node.js 测试
└── 最佳实践

下一步 #

现在你已经了解了 Vitest 的基本概念,接下来学习 安装与配置 开始实际使用 Vitest!

最后更新:2026-03-28