Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7863e54
feat!: fail the test when an asynchronous assertion is not awaited (#…
sheremet-va Aug 5, 2026
2e1be0c
feat(vm): support `require(esm)` in vm pools (#10829)
sheremet-va Aug 7, 2026
e512e7c
feat: report the duration breakdown as percentages (#10820)
sheremet-va Aug 7, 2026
3e063df
chore(deps): update dependency @antfu/ni to v30 (#10900)
renovate[bot] Aug 10, 2026
5ae4afd
docs: add TestMu AI to sponsors (#10904)
sheremet-va Aug 10, 2026
c890a47
feat!: share the Vite server between inline projects (#10848)
sheremet-va Aug 10, 2026
c6f5073
docs(browser): clarify special keys supported by userEvent.keyboard (…
shoaibyazdani Aug 11, 2026
7b607b0
fix(deps): update all non-major dependencies (#10898)
renovate[bot] Aug 11, 2026
726132d
fix(spy)!: preserve class mock prototype methods on instances (#10910)
sheremet-va Aug 11, 2026
fd768f0
docs: normalize ordered list number (#10895)
NoiseFan Aug 11, 2026
fe2fbfe
fix(snapshot): support no-unsafe-eval CSP by evaluating snapshot file…
hi-ogawa Aug 12, 2026
fedaf1b
feat(reporter): add custom GitHub Actions summary title (#10891)
heyJonBray Aug 12, 2026
d3697b6
docs: update migration guide (#10930)
sheremet-va Aug 12, 2026
79532d4
refactor(projects): cleanup comments, add more `debug` statements (#1…
sheremet-va Aug 14, 2026
4511691
fix(browser): disallow filter-only options in getBy* locators (fix #1…
Aug 14, 2026
2ded62f
fix(deps): update all non-major dependencies (#10966)
renovate[bot] Aug 17, 2026
5d198e2
chore: update agents file (#10952)
sheremet-va Aug 17, 2026
250585b
fix(reporters): display `test.name` in GitHub Actions reporter summar…
macarie Aug 17, 2026
253cea0
fix(snapshot): reject when `toMatchFileSnapshot` uses same snapshot f…
hi-ogawa Aug 18, 2026
1c2d55e
fix: combine multiple --project filters correctly (#10988)
sheremet-va Aug 18, 2026
2329ad4
docs: document expect.fail method (#11003)
AbhiPra24 Aug 19, 2026
0fce92b
docs: add cjs support status in common errors (#11002)
hi-ogawa Aug 19, 2026
b1ac9a6
feat(coverage): switch to `@vitest/istanbuljs` packages (#11053)
AriPerkkio Aug 26, 2026
8eea09d
fix(deps): update all non-major dependencies (#11043)
renovate[bot] Aug 26, 2026
caeb505
perf(vm): let environments opt out of the module graph prewarm (#11078)
sheremet-va Aug 28, 2026
10cf95d
feat: promote parseSpecifications out of experimental (#11087)
sheremet-va Aug 28, 2026
e885753
docs: document TZ limitation in thread pools (#11098)
sheremet-va Aug 29, 2026
e7065fe
feat: promote clearCache out of experimental (#11086)
sheremet-va Aug 29, 2026
a41164c
feat!: parse files statically in vitest list by default (#11088)
sheremet-va Aug 31, 2026
2793529
docs(en): merging all conflicts
docschina-bot Sep 1, 2026
3db6bc6
docs(cn): dissolve the conflict
NoiseFan Sep 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default ({ mode }: { mode: string }) => {
srcExclude: [
'**/guide/examples/*',
'**/guide/cli-generated.md',
'AGENTS.md',
],
locales: {
root: {
Expand Down Expand Up @@ -558,6 +559,10 @@ export default ({ mode }: { mode: string }) => {
text: 'projects',
link: '/config/projects',
},
{
text: 'sharedViteServer',
link: '/config/sharedviteserver',
},
{
text: 'isolate',
link: '/config/isolate',
Expand Down
5 changes: 5 additions & 0 deletions .vitepress/sponsors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ export const sponsors: SponsorTier[] = [
url: 'https://aerius.se/',
img: '/aerius.png',
},
{
name: 'TestMu AI',
url: 'https://www.testmuai.com/?utm_medium=sponsor&utm_source=vitest-dev',
img: '/testmuai.svg',
},
],
},
]
26 changes: 26 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Vitest Docs Guide

Guidance for working on the VitePress site in `docs/`. The root `AGENTS.md` applies here too.

## Building

- Local dev server: `pnpm docs` (from the repo root)
- Build with `pnpm docs:build` from the repo root; it sets the required env vars and regenerates the CLI table first
- The build type-checks code samples against the built workspace packages, so run `pnpm build` at the repo root first

## What fails the build

- Code blocks tagged `ts twoslash` are type-checked during `pnpm docs:build` only; the dev server skips twoslash and will not catch broken samples. A sample that intentionally fails needs `// @errors: <code>`; use `// ---cut---` and `// @filename:` to hide setup lines. Changing public types in `packages/` can break twoslash samples.
- Dead internal links fail the build. Every CLI option gets a generated link to `/config/<option>`, so a new option needs a matching `docs/config/<option>.md` page (or an entry in `skipConfig` in `docs/.vitepress/scripts/cli-generator.ts`).

## Conventions

- New docs pages are not auto-discovered: add a sidebar entry in `docs/.vitepress/config.ts` (the `/config`, `/guide`, and `/api` sidebars are hand-maintained arrays)
- Mark the version an API appeared in with `<Version>X.Y.Z</Version>` in the heading (the component renders the trailing `+` itself) plus an explicit `{#anchor}`
- Experimental APIs use `<Version type="experimental">X.Y.Z</Version>` with `<Experimental />`; deprecated APIs use `<Deprecated />`
- Config pages use frontmatter `title: <name> | Config`, `outline: deep`, and a `- **Type:** / - **Default:** / - **CLI:**` list

## Generated files (never edit by hand)

- `docs/guide/cli-generated.md` is generated from `packages/vitest/src/node/cli/cli-config.ts`; regenerate with `pnpm -C docs run cli-table` and commit the result
- `docs/.vitepress/contributor-names.json` is generated by `pnpm docs:contributors`
4 changes: 2 additions & 2 deletions api/advanced/reporters.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ export default new MyReporter()
function onCoverage(coverage: unknown): Awaitable<void>
```

当覆盖率结果处理完毕后调用此钩子。覆盖率提供者的报告器在此钩子之后调用。`coverage` 的类型取决于 `coverage.provider`。对于 Vitest 的默认内置提供者,我们可以从 `istanbul-lib-coverage` 包中导入类型:
当覆盖率结果处理完毕后调用此钩子。覆盖率提供者的报告器在此钩子之后调用。`coverage` 的类型取决于 `coverage.provider`。对于 Vitest 的默认内置提供者,我们可以从 `@vitest/istanbul-lib-coverage` 包中导入类型:

```ts
import type { CoverageMap } from 'istanbul-lib-coverage'
import type { CoverageMap } from '@vitest/istanbul-lib-coverage'

declare function onCoverage(coverage: CoverageMap): Awaitable<void>
```
Expand Down
10 changes: 9 additions & 1 deletion api/advanced/test-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,16 @@ vitest.config === vitest.projects[0].globalConfig
它基于项目的 root 路径和名称。请注意,不同操作系统的根路径并不一致,因此哈希值也会不同。

## vite
<!-- TODO: translation -->
This is project's [`ViteDevServer`](https://vite.dev/guide/api-javascript#vitedevserver). Note that the server is not necessarily exclusive to this project: other projects can reuse it when the [`sharedViteServer`](/config/sharedviteserver) option applies, and browser instances of the same cluster share a single browser server.

这是项目的 [`ViteDevServer`](https://vite.dev/guide/api-javascript#vitedevserver)。所有项目都有自己的 Vite 服务器。
## sharedViteServer

```ts
const sharedViteServer: boolean
```

`true` when the project reuses the Vite server of the config that declared it instead of resolving its own (see the [`sharedViteServer`](/config/sharedviteserver) option). The project that owns the server reports `false` even when other projects reuse it. To detect any two projects sharing a server (including browser instances), compare their [`vite`](#vite) references.

## browser

Expand Down
25 changes: 17 additions & 8 deletions api/advanced/vitest.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,17 +186,24 @@ function mergeReports(directory?: string): Promise<TestRunResult>
## collect

```ts
function collect(filters?: string[]): Promise<TestRunResult>
function collect(
filters?: string[],
options?: {
staticParse?: boolean
staticParseConcurrency?: number
}
): Promise<TestRunResult>
```

执行测试文件而不运行测试回调。`collect` 返回未处理的错误和 [测试模块](/api/advanced/test-module) 数组。它接受字符串过滤器以匹配测试文件 - 这些过滤器与 [CLI 支持的过滤器](/guide/filtering#cli) 相同。
根据 `staticParse` 的设置,此方法要么通过静态分析收集测试文件(默认行为),要么运行代码但不执行测试回调。`collect` 返回未处理的错误以及一个 [测试模块](/api/advanced/test-module) 数组。它接受用于匹配测试文件的字符串过滤器——这些过滤器与 [CLI 支持的过滤器](/guide/filtering#cli) 相同。

此方法根据配置的 `include`、`exclude` 和 `includeSource` 值解析 TestSpecification。有关更多信息,请参阅 [`project.globTestFiles`](/api/advanced/test-project#globtestfiles)。如果指定了 `--changed` 参数,则列表将被过滤为仅包含已更改的文件。

<!-- TODO: translation -->
::: warning
请注意,Vitest 不使用静态分析来收集测试。Vitest 将像运行常规测试一样在隔离环境中运行每个测试文件。

这使得此方法非常慢,除非我们在收集测试之前禁用隔离。
Note that since Vitest 5, the tests are collected by static analysis by default. If disabled via the second option, Vitest will run every test file in isolation, just like it runs regular tests. This would make this method very slow, unless you disable isolation manually before collecting tests.

:::

## start
Expand Down Expand Up @@ -591,10 +598,10 @@ Vitest 只会收集当前文件内定义的测试,绝不会跟随导入去其
无论是否从 `vitest` 入口点导入, Vitest 都会收集所有 `it` 、`test` 、`suite` 和 `describe` 的定义。
:::

## experimental_parseSpecifications <Version type="experimental">4.0.0</Version> <Experimental /> {#parsespecifications}
## parseSpecifications <Version>5.0.0</Version> {#parsespecifications}

```ts
function experimental_parseSpecifications(
function parseSpecifications(
specifications: TestSpecification[],
options?: {
concurrency?: number
Expand All @@ -604,14 +611,16 @@ function experimental_parseSpecifications(

此方法将从规范数组中 [收集测试用例](#parsespecification)。默认情况下,Vitest 每次仅会并行运行 `os.availableParallelism()` 数量的规范,以降低潜在的性能损耗。你可以通过第二个参数指定不同的并发数量。

## experimental_clearCache <Version type="experimental">4.0.11</Version> <Experimental /> {#clearcache}
## clearCache <Version>5.0.0</Version> {#clearcache}

```ts
function experimental_clearCache(): Promise<void>
function clearCache(): Promise<void>
```

删除所有 Vitest 缓存,包括 [`fsModuleCache`](/config/fsmodulecache)。

This was available since Vitest 4.0.11 as experimental `experimental_clearCache` method.

## experimental_getSourceModuleDiagnostic <Version type="experimental">4.0.15</Version> <Experimental /> {#getsourcemodulediagnostic}

```ts
Expand Down
9 changes: 8 additions & 1 deletion api/browser/interactivity.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,15 @@ function keyboard(text: string): Promise<void>
```

通过 `userEvent.keyboard` 可以触发键盘输入。如果任何输入有焦点,它就会在该输入中键入字符。否则,它将触发当前焦点元素(如果没有焦点元素,则为 `document.body`)上的键盘事件。
<!-- TODO: translation -->
此 API 支持 [user-event `keyboard` 语法](https://testing-library.com/docs/user-event/keyboard)。 Common special keys that can be referenced inside the braces include:

此 API 支持 [user-event `keyboard` 语法](https://testing-library.com/docs/user-event/keyboard)。
- **Modifiers:** `{Shift}`, `{Control}`, `{Alt}`, `{Meta}`
- **Navigation:** `{ArrowUp}`, `{ArrowDown}`, `{ArrowLeft}`, `{ArrowRight}`, `{Home}`, `{End}`, `{PageUp}`, `{PageDown}`
- **Editing:** `{Backspace}`, `{Delete}`, `{Insert}`, `{Tab}`, `{Enter}`, `{Escape}`
- **Function keys:** `{F1}` through `{F12}`

Note: The exact set of supported keys may vary depending on the underlying browser provider (Playwright vs WebdriverIO). If a key press doesn't trigger the expected behavior, consult your provider's documentation or file an issue.

```ts
import { userEvent } from 'vitest/browser'
Expand Down
2 changes: 1 addition & 1 deletion api/browser/locators.md
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ page.getByRole('button')
## filter

```ts
function filter(options: LocatorOptions): Locator
function filter(options: LocatorFilterOptions): Locator
```

此方法会根据选项(例如按文本过滤)缩小定位器范围。可通过链式调用应用多个过滤器。
Expand Down
30 changes: 24 additions & 6 deletions api/expect.md
Original file line number Diff line number Diff line change
Expand Up @@ -1876,9 +1876,7 @@ test('buyApples returns new stock id', async () => {
```

:::warning
如果断言没有被异步等待,那么我们将得到一个误报测试,这个测试每次都能通过。为了确保断言确实被调用,我们可以尝试使用 [`expect.assertions(number)`](#expect-assertions)。

自 Vitest 3 起,如果一个方法没有被等待(await),Vitest 会在测试结束时显示警告。到了 Vitest 4 ,如果断言没有被等待,测试将被标记为 "failed" 。
如果断言没有被等待,测试将被标记为 "failed" 。
:::

## rejects
Expand Down Expand Up @@ -1907,9 +1905,7 @@ test('buyApples throws an error when no id provided', async () => {
```

:::warning
如果断言没有被等待执行,那么我们将得到一个误报测试,这个测试每次都能通过。为了确保断言实际上被调用了,我们可以尝试使用 [`expect.assertions(number)`](#expect-assertions)。

自 Vitest 3 起,若方法未被异步等待( await ),Vitest 将在测试结束时显示警告。而在 Vitest 4 中,若断言未被异步等待,则测试将被标记为 "failed" 。
如果断言没有被等待,测试将被标记为 "failed" 。
:::

## expect.assertions
Expand Down Expand Up @@ -2024,6 +2020,28 @@ test.each(errorDirs)('build fails with "%s"', async (dir) => {
}
})
```
<!-- TODO: translation -->
## expect.fail

- **Type:** `(message?: string) => never`

Explicitly forces a test failure with an optional custom message.

For example, you can use it inside a `try/catch` block to ensure an error was thrown:

```ts
import { expect, test } from 'vitest'

test('fails when error is not thrown', async () => {
try {
await performAction()
expect.fail('Expected performAction to throw an error')
}
catch (error) {
expect(error).toBeInstanceOf(CustomError)
}
})
```

## expect.anything

Expand Down
11 changes: 6 additions & 5 deletions api/mock.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ BobsBucket === 2 // true
mockFn.mock.calls[0][0] === 0 // true
mockFn.mock.calls[1][0] === 1 // true
```
<!-- TODO: translation -->
If the implementation is a class, the mock's `prototype` is re-pointed to the implementation's prototype, so constructed instances see its prototype methods and pass `instanceof` checks against it. See [Mocking Classes](/guide/mocking/classes) for details.

## mockImplementationOnce

Expand Down Expand Up @@ -284,13 +286,12 @@ function mockReset(): Mock<T>

该方法会先执行与 [`mockClear`](#mockClear) 相同的清理,再重置 mock 的实现,并一并清除所有一次性(once)设定。

注意:
注意:如果 mock 由 `vi.fn()` 创建,重置后其函数体将变为空实现,默认返回 `undefined`。如果由 `vi.fn(impl)` 创建,重置后实现会恢复为传入的 `impl`。

- 若 mock 由 `vi.fn()` 创建,重置后其函数体将变为空实现,默认返回 `undefined`。
<!-- TODO: translation -->
The mock's `prototype` chain follows along: it reverts to the original class for `vi.fn(impl)` and `vi.spyOn()`, and to a plain object for `vi.fn()`, so instances constructed after the reset no longer pass `instanceof` checks against a previously set class implementation.

- 若由 `vi.fn(impl)` 创建,重置后实现会恢复为传入的 `impl`。

当我们想将模拟 restore 为其原始状态时,这很有用。
适用于想将模拟重置为初始状态。

```ts
const person = {
Expand Down
13 changes: 9 additions & 4 deletions api/vi.md
Original file line number Diff line number Diff line change
Expand Up @@ -467,15 +467,18 @@ expect(getApples).toHaveNthReturnedWith(2, 5)
`vi.fn` 同样支持传入 class 作为参数:

```ts
const Cart = vi.fn(
class {
get = () => 0
const Cart = vi.fn(class {
get() {
return 0
}
)
})

const cart = new Cart()
expect(Cart).toHaveBeenCalled()
expect(cart.get()).toBe(0)
```
<!-- TODO: translation -->
Instances keep the prototype chain of the implementation class, so its prototype methods are available on instances, and `instanceof` checks against the implementation class pass. See [Mocking Classes](/guide/mocking/classes) for details.

### vi.mockObject <Version>3.2.0</Version>

Expand Down Expand Up @@ -616,6 +619,8 @@ const spy = vi
```

如果传入箭头函数, mock 被调用时将抛出 [`<anonymous> is not a constructor` 错误](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_constructor)。
<!-- TODO: translation -->
With a class implementation, instances keep the prototype chain of that class: prototype methods like `getApples` are available on instances, and `instanceof` checks against the implementation class pass. See [Mocking Classes](/guide/mocking/classes) for details.

::: tip
若运行环境支持 [显式资源管理](https://github.com/tc39/proposal-explicit-resource-management) ,可将 `const` 替换为 `using`。离开当前块级作用域时,系统会自动对被 mock 的函数调用 `mockRestore`,特别适用于已打 spy 的方法。
Expand Down
4 changes: 2 additions & 2 deletions config/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ Vitest 默认不会将 API 暴露到互联网,仅在 `localhost` 上监听。

- **类型:** `boolean`
- **默认值:** `true` 表示未暴露在公共网络中,`false` 则表示已暴露

允许通过 API 运行任何测试文件。适用于 [UI 模式](/guide/ui) 中能够运行代码的交互元素(以及其背后的服务端代码)。此选项还会限制可间接执行代码的特权浏览器 API,例如通过 [`cdp()`](/api/browser/context#cdp) 直接访问 Chrome DevTools Protocol。
<!-- TODO: translation -->
允许通过 API 运行任何测试文件。适用于 [UI 模式](/guide/ui) 中能够运行代码的交互元素(以及其背后的服务端代码)。In Browser Mode, this option also gates indirect code execution, including evaluating external `.snap` files on the server and accessing raw Chrome DevTools Protocol through [`cdp()`](/api/browser/context#cdp).
10 changes: 6 additions & 4 deletions config/coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ npx vitest --coverage.enabled --coverage.provider=istanbul
以 glob 模式指定需要统计覆盖率的文件列表。默认情况下,仅包含被测试覆盖的文件。

建议在匹配规则中传递文件扩展名。
<!-- TODO: translation -->
Patterns are matched against each file's path relative to the project root. A pattern with no glob wildcard is treated as a directory and matches everything inside it, so `include: ['src']` is equivalent to `include: ['src/**']`.

更多示例请参阅 [在覆盖率报告中包含和排除文件](/guide/coverage.html#including-and-excluding-files-from-coverage-report)
See [Including and excluding files from coverage report](/guide/coverage.html#including-and-excluding-files-from-coverage-report) for examples.

## coverage.exclude

Expand All @@ -54,7 +56,7 @@ npx vitest --coverage.enabled --coverage.provider=istanbul
- **可用的测试提供者:** `'v8' | 'istanbul'`
- **命令行终端:** `--coverage.exclude=<path>`, `--coverage.exclude=<path1> --coverage.exclude=<path2>`

以 glob 模式指定从代码覆盖率中排除的文件列表。
以 glob 模式指定从代码覆盖率中排除的文件列表。Patterns are matched the same way as [`coverage.include`](#coverage-include).

更多示例请参阅 [在覆盖率报告中包含和排除文件](/guide/coverage.html#including-and-excluding-files-from-coverage-report)。

Expand Down Expand Up @@ -96,7 +98,7 @@ npx vitest --coverage.enabled --coverage.provider=istanbul
- **可用的测试提供者:** `'v8' | 'istanbul'`
- **命令行终端:** `--coverage.reporter=<reporter>`, `--coverage.reporter=<reporter1> --coverage.reporter=<reporter2>`

要使用的代码覆盖率报告器。所有报告器的详细列表请参阅 [istanbul 文档](https://istanbul.js.org/docs/advanced/alternative-reporters/)。关于报告器特定选项的详细信息请参阅 [`@types/istanbul-reports`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/276d95e4304b3670eaf6e8e5a7ea9e265a14e338/types/istanbul-reports/index.d.ts)。
要使用的代码覆盖率报告器。所有报告器的详细列表请参阅 [istanbul 文档](https://istanbul.js.org/docs/advanced/alternative-reporters/)。关于报告器特定选项的详细信息请参阅 [`@vitest/istanbul-lib-report`](https://github.com/vitest-dev/istanbuljs/tree/main/packages/istanbul-lib-report/src/reports)。

报告器有三种不同的类型:

Expand Down Expand Up @@ -457,7 +459,7 @@ Vitest 会将所有文件(包括匹配 glob 模式的文件)计入全局覆
- **类型:** `(options: InstrumenterOptions) => CoverageInstrumenter`
- **可用的测试提供者:** `'istanbul'`

用于替代默认 `istanbul-lib-instrument` 的自定义检测器工厂函数。Vitest 在初始化期间调用该工厂函数一次,并对每个文件复用返回的检测器。Istanbul 管道的其余部分(收集、合并、报告)保持不变。
用于替代默认 `@vitest/istanbul-lib-instrument` 的自定义检测器工厂函数。Vitest 在初始化期间调用该工厂函数一次,并对每个文件复用返回的检测器。Istanbul 管道的其余部分(收集、合并、报告)保持不变。

该工厂函数接收包含 Vitest 运行时覆盖率设置的 `InstrumenterOptions` 对象,必须返回实现 `CoverageInstrumenter` 接口的对象。两种类型均从 `vitest/node` 导出。

Expand Down
4 changes: 4 additions & 0 deletions config/env.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ outline: deep
- **类型:** `Partial<NodeJS.ProcessEnv>`

测试期间在 `process.env` 和 `import.meta.env` 中可用的环境变量。这些变量在主进程中不可用(例如在 `globalSetup` 中)。
<!-- TODO: translation -->
::: warning
`TZ` set here does not change the time zone in `threads` and `vmThreads` pools. See [Time Zone Does Not Change in Worker Threads](/guide/common-errors#time-zone-does-not-change-in-worker-threads).
:::
Loading
Loading