vitest

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Vitest

Vitest

Next generation testing framework powered by Vite.
由Vite驱动的下一代测试框架。

Quick Navigation

快速导航

  • Test API - test, describe, hooks
  • Expect API - matchers and assertions
  • Mocking - vi.fn, vi.mock, fake timers
  • Configuration - vitest.config.ts options
  • CLI - command line reference
  • Browser Mode - real browser testing
  • 测试API - test、describe、钩子函数
  • 断言API - 匹配器与断言
  • 模拟功能 - vi.fn、vi.mock、假计时器
  • 配置 - vitest.config.ts配置选项
  • 命令行界面 - 命令行参考
  • 浏览器模式 - 真实浏览器测试

When to Use

适用场景

  • Testing Vite-based applications (shared config)
  • Need Jest-compatible API with native ESM support
  • Component testing in real browser
  • Fast watch mode with HMR
  • TypeScript testing without extra config
  • Parallel test execution
  • 测试基于Vite的应用(共享配置)
  • 需要兼容Jest且支持原生ESM的API
  • 真实浏览器中的组件测试
  • 带有HMR的快速监听模式
  • 无需额外配置的TypeScript测试
  • 并行测试执行

Installation

安装

bash
npm install -D vitest
Requirements: Vite >=v6.0.0, Node >=v20.0.0
bash
npm install -D vitest
要求: Vite >=v6.0.0,Node >=v20.0.0

Quick Start

快速开始

js
// sum.js
export function sum(a, b) {
  return a + b;
}
js
// sum.test.js
import { expect, test } from "vitest";
import { sum } from "./sum.js";

test("adds 1 + 2 to equal 3", () => {
  expect(sum(1, 2)).toBe(3);
});
json
// package.json
{
  "scripts": {
    "test": "vitest",
    "test:run": "vitest run",
    "coverage": "vitest run --coverage"
  }
}
js
// sum.js
export function sum(a, b) {
  return a + b;
}
js
// sum.test.js
import { expect, test } from "vitest";
import { sum } from "./sum.js";

test("adds 1 + 2 to equal 3", () => {
  expect(sum(1, 2)).toBe(3);
});
json
// package.json
{
  "scripts": {
    "test": "vitest",
    "test:run": "vitest run",
    "coverage": "vitest run --coverage"
  }
}

Configuration

配置

ts
// vitest.config.ts (recommended)
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    globals: true, // Enable global test APIs
    environment: "jsdom", // Browser-like environment
    include: ["**/*.{test,spec}.{js,ts,jsx,tsx}"],
    coverage: {
      provider: "v8",
      reporter: ["text", "html"],
    },
  },
});
Or extend Vite config:
ts
// vite.config.ts
/// <reference types="vitest/config" />
import { defineConfig } from "vite";

export default defineConfig({
  test: {
    // test options
  },
});
ts
// vitest.config.ts (推荐)
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    globals: true, // 启用全局测试API
    environment: "jsdom", // 类浏览器环境
    include: ["**/*.{test,spec}.{js,ts,jsx,tsx}"],
    coverage: {
      provider: "v8",
      reporter: ["text", "html"],
    },
  },
});
或者扩展Vite配置:
ts
// vite.config.ts
/// <reference types="vitest/config" />
import { defineConfig } from "vite";

export default defineConfig({
  test: {
    // 测试选项
  },
});

Test File Naming

测试文件命名

By default, tests must contain
.test.
or
.spec.
in filename:
  • sum.test.js
  • sum.spec.ts
  • __tests__/sum.js
默认情况下,测试文件名中必须包含
.test.
.spec.
  • sum.test.js
  • sum.spec.ts
  • __tests__/sum.js

Key Commands

常用命令

bash
undefined
bash
undefined

Watch mode (default)

监听模式(默认)

vitest
vitest

Single run

单次运行

vitest run
vitest run

With coverage

生成覆盖率报告

vitest run --coverage
vitest run --coverage

Filter by file/test name

按文件/测试名称过滤

vitest sum vitest -t "should add"
vitest sum vitest -t "should add"

UI mode

UI模式

vitest --ui
vitest --ui

Browser tests

浏览器测试

vitest --browser.enabled
undefined
vitest --browser.enabled
undefined

Common Patterns

常见模式

Basic Test

基础测试

ts
import { describe, it, expect, beforeEach } from "vitest";

describe("Calculator", () => {
  let calc: Calculator;

  beforeEach(() => {
    calc = new Calculator();
  });

  it("adds numbers", () => {
    expect(calc.add(1, 2)).toBe(3);
  });

  it("throws on invalid input", () => {
    expect(() => calc.add("a", 1)).toThrow();
  });
});
ts
import { describe, it, expect, beforeEach } from "vitest";

describe("Calculator", () => {
  let calc: Calculator;

  beforeEach(() => {
    calc = new Calculator();
  });

  it("adds numbers", () => {
    expect(calc.add(1, 2)).toBe(3);
  });

  it("throws on invalid input", () => {
    expect(() => calc.add("a", 1)).toThrow();
  });
});

Mocking

模拟功能

ts
import { vi, expect, test } from "vitest";
import { fetchUser } from "./api";

vi.mock("./api", () => ({
  fetchUser: vi.fn(),
}));

test("uses mocked API", async () => {
  vi.mocked(fetchUser).mockResolvedValue({ name: "John" });

  const user = await fetchUser(1);

  expect(fetchUser).toHaveBeenCalledWith(1);
  expect(user.name).toBe("John");
});
ts
import { vi, expect, test } from "vitest";
import { fetchUser } from "./api";

vi.mock("./api", () => ({
  fetchUser: vi.fn(),
}));

test("uses mocked API", async () => {
  vi.mocked(fetchUser).mockResolvedValue({ name: "John" });

  const user = await fetchUser(1);

  expect(fetchUser).toHaveBeenCalledWith(1);
  expect(user.name).toBe("John");
});

Snapshot Testing

快照测试

ts
import { expect, test } from "vitest";

test("matches snapshot", () => {
  const result = generateConfig();
  expect(result).toMatchSnapshot();
});

// Inline snapshot (auto-updates)
test("inline snapshot", () => {
  expect({ foo: "bar" }).toMatchInlineSnapshot();
});
ts
import { expect, test } from "vitest";

test("matches snapshot", () => {
  const result = generateConfig();
  expect(result).toMatchSnapshot();
});

// 内联快照(自动更新)
test("inline snapshot", () => {
  expect({ foo: "bar" }).toMatchInlineSnapshot();
});

Async Testing

异步测试

ts
import { expect, test } from "vitest";

test("async/await", async () => {
  const result = await fetchData();
  expect(result).toBeDefined();
});

test("resolves", async () => {
  await expect(Promise.resolve("ok")).resolves.toBe("ok");
});

test("rejects", async () => {
  await expect(Promise.reject(new Error())).rejects.toThrow();
});
ts
import { expect, test } from "vitest";

test("async/await", async () => {
  const result = await fetchData();
  expect(result).toBeDefined();
});

test("resolves", async () => {
  await expect(Promise.resolve("ok")).resolves.toBe("ok");
});

test("rejects", async () => {
  await expect(Promise.reject(new Error())).rejects.toThrow();
});

Fake Timers

假计时器

ts
import { vi, expect, test, beforeEach, afterEach } from "vitest";

beforeEach(() => {
  vi.useFakeTimers();
});

afterEach(() => {
  vi.useRealTimers();
});

test("advances time", () => {
  const callback = vi.fn();
  setTimeout(callback, 1000);

  vi.advanceTimersByTime(1000);

  expect(callback).toHaveBeenCalled();
});
ts
import { vi, expect, test, beforeEach, afterEach } from "vitest";

beforeEach(() => {
  vi.useFakeTimers();
});

afterEach(() => {
  vi.useRealTimers();
});

test("advances time", () => {
  const callback = vi.fn();
  setTimeout(callback, 1000);

  vi.advanceTimersByTime(1000);

  expect(callback).toHaveBeenCalled();
});

Jest Migration

Jest迁移

Most Jest code works with minimal changes:
diff
- import { jest } from '@jest/globals'
+ import { vi } from 'vitest'

- jest.fn()
+ vi.fn()

- jest.mock('./module')
+ vi.mock('./module')

- jest.useFakeTimers()
+ vi.useFakeTimers()
Key differences:
  • Use
    vi
    instead of
    jest
  • Globals not enabled by default (add
    globals: true
    )
  • vi.mock
    is hoisted (use
    vi.doMock
    for non-hoisted)
  • No
    jest.requireActual
    (use
    vi.importActual
    )
大多数Jest代码只需少量修改即可运行:
diff
- import { jest } from '@jest/globals'
+ import { vi } from 'vitest'

- jest.fn()
+ vi.fn()

- jest.mock('./module')
+ vi.mock('./module')

- jest.useFakeTimers()
+ vi.useFakeTimers()
主要差异:
  • 使用
    vi
    替代
    jest
  • 默认未启用全局变量(需添加
    globals: true
  • vi.mock
    会被提升(非提升场景使用
    vi.doMock
  • 没有
    jest.requireActual
    (使用
    vi.importActual
    替代)

Environment Selection

环境选择

ts
// vitest.config.ts
{
  test: {
    environment: 'jsdom', // or 'happy-dom', 'node', 'edge-runtime'
  }
}

// Per-file (docblock at top)
/** @vitest-environment jsdom */
ts
// vitest.config.ts
{
  test: {
    environment: 'jsdom', // 或'happy-dom'、'node'、'edge-runtime'
  }
}

// 单文件配置(顶部文档块)
/** @vitest-environment jsdom */

TypeScript

TypeScript

json
// tsconfig.json
{
  "compilerOptions": {
    "types": ["vitest/globals"]
  }
}
json
// tsconfig.json
{
  "compilerOptions": {
    "types": ["vitest/globals"]
  }
}

References

参考资料

See
references/
directory for detailed documentation on:
  • Test API and hooks
  • All expect matchers
  • Mocking functions and modules
  • Configuration options
  • CLI commands
  • Browser mode testing
请查看
references/
目录获取以下内容的详细文档:
  • 测试API与钩子
  • 所有断言匹配器
  • 函数与模块模拟
  • 配置选项
  • CLI命令
  • 浏览器模式测试

Links

链接