特性 
- Vite 的配置、转换器、解析器和插件。
 - 使用与你的应用程序相同的配置来运行测试!
 - 智能即时监听模式,就像 Vite 中的热模块替换(HMR)!
 - 适用于 Vue、React、Svelte、Lit 等的组件测试
 - 开箱即用的 TypeScript / JSX 支持
 - 优先支持 ESM(ECMAScript 模块)和顶层 await
 - 通过 Tinypool 实现 Workers 多线程
 - 通过 Tinybench 支持基准测试
 - 提供过滤、超时、并发等功能以加速测试套件和测试用例
 - 支持 工作区(Workspace)
 - 兼容 Jest 的快照(Snapshot)
 - 内置用于断言的 Chai + 兼容 Jest expect 的 API
 - 内置用于模拟(mocking)的 Tinyspy
 - 使用 happy-dom 或 jsdom 进行 DOM 模拟
 - 通过 v8 或 istanbul 进行代码覆盖率检测
 - 类似 Rust 的 源代码内测试(in-source testing)
 - 通过 expect-type 进行类型测试
 
在测试、开发和构建之间共享配置 
使用 Vite 的配置、转换器、解析器和插件,以便使用与你的应用程序相同的设置来运行测试。
请参阅 配置 Vitest 了解更多信息。
监听模式 
$ vitest当你修改源代码或测试文件时,Vitest 会智能地搜索模块依赖图,并且只重新运行相关的测试,就像 Vite 中的 HMR(热模块替换)一样!
vitest 默认在开发环境中以监听模式启动,而在 CI 环境(当 process.env.CI 存在时)中以运行模式启动。你可以使用 vitest watch 或 vitest run 显式指定所需的模式。
开箱即用的通用 Web 习惯 
开箱即用的 ES 模块 / TypeScript / JSX 支持 / PostCSS
线程 
默认情况下,Vitest 使用 node:worker_threads 通过 Tinypool (一个轻量级的 Piscina 分支) 在多个线程中运行测试文件,从而允许测试同时运行。如果你的测试代码与多线程不兼容,你可以切换到 --pool=forks,它使用 node:child_process 通过 Tinypool 在多个进程中运行测试。
要以单个线程或进程运行测试,请参阅 poolOptions。
Vitest 会隔离每个文件的环境,因此一个文件中的环境变更不会影响其他文件。可以通过将 --no-isolate 传递给 CLI 来禁用隔离(牺牲正确性换取运行性能)。
测试过滤 
Vitest 提供了多种方法来缩小要运行的测试范围,以便加速测试,使你可以更专注于开发。
在 测试过滤 了解更多。
并发运行测试 
在多个测试用例中使用 .concurrent 可以并行运行它们。
import { describe, it } from 'vitest';
// 标记为并发的两个测试将并行运行
describe('suite', () => {
  it('serial test', async () => {
    /* ... */
  });
  it.concurrent('concurrent test 1', async ({ expect }) => {
    /* ... */
  });
  it.concurrent('concurrent test 2', async ({ expect }) => {
    /* ... */
  });
});如果在测试套件上使用 .concurrent,则该套件中的每个测试都将并行运行。
import { describe, it } from 'vitest';
// 该套件中的所有测试都将并行运行
describe.concurrent('suite', () => {
  it('concurrent test 1', async ({ expect }) => {
    /* ... */
  });
  it('concurrent test 2', async ({ expect }) => {
    /* ... */
  });
  it.concurrent('concurrent test 3', async ({ expect }) => {
    /* ... */
  });
});你还可以将 .skip、.only 和 .todo 与并发套件和测试一起使用。在 API 参考 中阅读更多内容。
WARNING
当运行并发测试时,快照和断言必须使用来自本地 测试上下文 的 expect,以确保检测到正确的测试。
快照 
兼容 Jest 的快照支持。
import { expect, it } from 'vitest';
it('renders correctly', () => {
  const result = render();
  expect(result).toMatchSnapshot();
});在 快照 了解更多。
Chai 和 Jest expect 兼容性 
Chai 内置用于断言,并提供与 Jest expect 兼容的 API。
请注意,如果你使用了添加匹配器的第三方库,将 test.globals 设置为 true 将提供更好的兼容性。
模拟 
Tinyspy 内置用于通过 vi 对象上的 jest 兼容 API 进行模拟。
import { expect, vi } from 'vitest';
const fn = vi.fn();
fn('hello', 1);
expect(vi.isMockFunction(fn)).toBe(true);
expect(fn.mock.calls[0]).toEqual(['hello', 1]);
fn.mockImplementation(arg => arg);
fn('world', 2);
expect(fn.mock.results[1].value).toBe('world');Vitest 支持使用 happy-dom 或 jsdom 来模拟 DOM 和浏览器 API。它们不包含在 Vitest 中,你可能需要安装它们:
$ npm i -D happy-dom
# or
$ npm i -D jsdom之后,修改配置文件中的 environment 选项:
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
  test: {
    environment: 'happy-dom', // or 'jsdom', 'node'
  },
});在 模拟 了解更多。
覆盖率 
Vitest 支持通过 v8 进行原生代码覆盖率检测和通过 istanbul 进行插桩代码覆盖率检测。
{
  "scripts": {
    "test": "vitest",
    "coverage": "vitest run --coverage"
  }
}在 覆盖率 了解更多。
源代码内测试 
Vitest 还提供了一种在源代码中运行测试的方法,与实现代码一起,类似于 Rust 的模块测试。
这使得测试与实现代码共享相同的闭包,从而可以在不导出私有状态的情况下进行测试。同时,也缩短了开发过程中的反馈循环。
// src/index.ts
// 实现代码
export function add(...args: number[]) {
  return args.reduce((a, b) => a + b, 0);
}
// 源代码内测试套件
if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest;
  it('add', () => {
    expect(add()).toBe(0);
    expect(add(1)).toBe(1);
    expect(add(1, 2, 3)).toBe(6);
  });
}在 源代码内测试 了解更多。
基准测试 实验性 
从 Vitest 0.23.0 开始,你可以通过 Tinybench 使用 bench 函数运行基准测试,以比较性能结果。
import { bench, describe } from 'vitest';
describe('sort', () => {
  bench('normal', () => {
    const x = [1, 5, 4, 2, 3];
    x.sort((a, b) => {
      return a - b;
    });
  });
  bench('reverse', () => {
    const x = [1, 5, 4, 2, 3];
    x.reverse().sort((a, b) => {
      return a - b;
    });
  });
});类型测试 实验性 
从 Vitest 0.25.0 开始,你可以编写测试来捕获类型回归。Vitest 附带 expect-type 包,为你提供类似且易于理解的 API。
import { assertType, expectTypeOf } from 'vitest';
import { mount } from './mount.js';
test('my types work properly', () => {
  expectTypeOf(mount).toBeFunction();
  expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>();
  // @ts-expect-error name is a string
  assertType(mount({ name: 42 }));
});