跳至内容

功能

通过视频学习如何编写第一个测试

测试、开发和构建之间的共享配置

Vite 的配置、转换器、解析器和插件。使用与应用程序相同的设置运行测试。

配置 Vitest 中了解更多信息。

观察模式

bash
$ vitest

当您修改源代码或测试文件时,Vitest 会智能地搜索模块图,并且只重新运行相关的测试,就像 Vite 中的 HMR 工作方式一样!

vitest 在 **开发环境中默认以观察模式启动**,在 CI 环境中(当 process.env.CI 存在时)智能地以运行模式启动。您可以使用 vitest watchvitest run 明确指定所需的模式。

开箱即用的常见 Web 惯例

开箱即用的 ES 模块 / TypeScript / JSX 支持 / PostCSS

线程

默认情况下,Vitest 使用 node:worker_threads 通过 TinypoolPiscina 的轻量级分支)在多个线程中运行测试文件,允许测试同时运行。如果您的测试正在运行与多线程不兼容的代码,您可以切换到 --pool=forks,它使用 node:child_process 通过 Tinypool 在多个进程中运行测试。

要以单线程或单进程运行测试,请参阅 poolOptions

Vitest 还隔离每个文件的环境,因此一个文件中的环境变动不会影响其他文件。可以通过将 --no-isolate 传递给 CLI 来禁用隔离(以运行性能换取正确性)。

测试过滤

Vitest 提供了许多方法来缩小要运行的测试范围,以便加快测试速度,让您专注于开发。

详细了解 测试过滤

并发运行测试

在连续测试中使用 .concurrent 以并行运行它们。

ts
import { ,  } from 'vitest'

// The two tests marked with concurrent will be run in parallel
('suite', () => {
  ('serial test', async () => { /* ... */ })
  .('concurrent test 1', async ({  }) => { /* ... */ })
  .('concurrent test 2', async ({  }) => { /* ... */ })
})

如果您在套件上使用 .concurrent,则其中的每个测试都将并行运行。

ts
import { ,  } from 'vitest'

// All tests within this suite will be run in parallel
.('suite', () => {
  ('concurrent test 1', async ({  }) => { /* ... */ })
  ('concurrent test 2', async ({  }) => { /* ... */ })
  .('concurrent test 3', async ({  }) => { /* ... */ })
})

您也可以将 .skip.only.todo 与并发套件和测试一起使用。在 API 参考 中了解更多信息。

警告

在运行并发测试时,快照和断言必须使用来自本地 测试上下文expect 以确保检测到正确的测试。

快照

与 Jest 兼容 的快照支持。

ts
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。

ts
import { ,  } from 'vitest'

const  = .()

('hello', 1)

(.()).(true)
(..[0]).(['hello', 1])

.( => )

('world', 2)

(..[1].).('world')

Vitest 支持 happy-domjsdom 用于模拟 DOM 和浏览器 API。它们不包含在 Vitest 中,您可能需要安装它们

bash
$ npm i -D happy-dom
# or
$ npm i -D jsdom

之后,更改配置文件中的 environment 选项

ts
// vitest.config.ts
import {  } from 'vitest/config'

export default ({
  : {
    : 'happy-dom', // or 'jsdom', 'node'
  },
})

模拟 中了解更多信息。

覆盖率

Vitest 支持通过 v8 进行原生代码覆盖率,以及通过 istanbul 进行代码插桩覆盖率。

json
{
  "scripts": {
    "test": "vitest",
    "coverage": "vitest run --coverage"
  }
}

覆盖率 中了解更多信息。

源代码测试

Vitest 还提供了一种在源代码中与实现一起运行测试的方法,类似于 Rust 的模块测试

这使得测试与实现共享相同的闭包,并且能够在不导出私有状态的情况下进行测试。同时,它也使开发的反馈循环更加紧密。

ts
// src/index.ts

// the implementation
export function add(...args: number[]) {
  return args.reduce((a, b) => a + b, 0)
}

// in-source test suites
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 开始,您可以使用 bench 函数通过 Tinybench 运行基准测试,以比较性能结果。

ts
import { ,  } from 'vitest'

('sort', () => {
  ('normal', () => {
    const  = [1, 5, 4, 2, 3]
    .((, ) => {
      return  - 
    })
  })

  ('reverse', () => {
    const  = [1, 5, 4, 2, 3]
    .().((, ) => {
      return  - 
    })
  })
})
Benchmark reportBenchmark report

类型测试 实验性

从 Vitest 0.25.0 开始,您可以 编写测试 来捕获类型回归。Vitest 附带 expect-type 包,为您提供类似且易于理解的 API。

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