diff --git a/.vitepress/config.ts b/.vitepress/config.ts index f5e1e610..6ef068ba 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -296,9 +296,9 @@ export default ({ mode }: { mode: string }) => { collapsed: false, items: [ { - text: '浏览器模式配置', + text: '浏览器配置', link: '/guide/browser/config', - docFooterText: '浏览器模式配置 | 浏览器模式', + docFooterText: '浏览器配置 | 浏览器模式', }, { text: '配置 Playwright', @@ -353,9 +353,9 @@ export default ({ mode }: { mode: string }) => { collapsed: false, items: [ { - text: '多种设置', + text: '多环境配置', link: '/guide/browser/multiple-setups', - docFooterText: '多种设置 | 浏览器模式', + docFooterText: '多环境配置 | 浏览器模式', }, { text: '组件测试', @@ -567,11 +567,11 @@ function guide(): DefaultTheme.SidebarItem[] { link: '/guide/reporters', }, { - text: '测试覆盖率', + text: '覆盖率', link: '/guide/coverage', }, { - text: '测试快照', + text: '快照', link: '/guide/snapshot', }, { @@ -614,7 +614,7 @@ function guide(): DefaultTheme.SidebarItem[] { ], }, { - text: '并行执行', + text: '并行性', link: '/guide/parallelism', }, { @@ -622,7 +622,7 @@ function guide(): DefaultTheme.SidebarItem[] { link: '/guide/testing-types', }, { - text: 'UI模式', + text: 'UI 模式', link: '/guide/ui', }, { diff --git a/advanced/api.md b/advanced/api.md deleted file mode 100644 index 40abb3b4..00000000 --- a/advanced/api.md +++ /dev/null @@ -1,351 +0,0 @@ ---- -outline: [2, 3] ---- - -# Node API - -::: warning -Vitest 暴露了实验性的私有 API。由于可能不遵循语义化版本规范(SemVer),因此可能会出现不兼容的更改,请在使用 Vitest 时锁定版本。 -::: - -## 启动 Vitest - -你可以使用 Vitest 的 Node API 开始运行 Vitest 测试: - -```js -import { startVitest } from 'vitest/node' - -const vitest = await startVitest('test') - -await vitest?.close() -``` - -如果测试可以启动,则 `startVitest` 函数返回 `Vitest` 实例。 如果出现以下情况之一,则返回 `undefined`: - -- Vitest 未找到 `vite` 包 (通常与 Vitest 一起安装) -- 如果启用了 `coverage`,并且运行模式为 "test",但并未安装 "coverage" 包(`@vitest/coverage-v8` 或 `@vitest/coverage-istanbul`) -- 如果未安装环境包 (`jsdom`/`happy-dom`/`@edge-runtime/vm`) - -如果在运行期间返回 `undefined` 或者测试失败, Vitest 会将 `process.exitCode` 设置为 `1`。 - -如果未启用监视模式,Vitest 将会调用 `close` 方法。 - -如果启用了监视模式并且终端支持 TTY, 则 Vitest 会注册控制台快捷键。 - -你可以将过滤器列表作为第二个参数传递下去。Vitest 将仅运行包含其文件路径中至少一个传递字符串的测试。 - -此外,你可以使用第三个参数传递 CLI 参数,这将覆盖任何测试配置选项。 - -或者,你可以将完整的 Vite 配置作为第四个参数传递进去,这将优先于任何其他用户定义的选项。 - -运行测试后,您可以从 `state.getFiles` API 获取结果: - -```ts -const vitest = await startVitest('test') - -console.log(vitest.state.getFiles()) // [{ type: 'file', ... }] -``` - -自 Vitest 2.1 起,建议使用["Reported Tasks" API](/advanced/reporters#reported-tasks) 和 `state.getFiles`。今后,Vitest 将直接返回这些对象: - -```ts -const vitest = await startVitest('test') - -const [fileTask] = vitest.state.getFiles() -const testFile = vitest.state.getReportedEntity(fileTask) -``` - -## 创建 Vitest - -你可以使用 `createVitest` 函数创建自己的 Vitest 实例. 它返回与 `startVitest` 相同的 `Vitest` 实例, 但不会启动测试,也不会验证已安装的包。 - -```js -import { createVitest } from 'vitest/node' - -const vitest = await createVitest('test', { - watch: false, -}) -``` - -## parseCLI - -你可以使用此方法来解析 CLI 参数。它接受字符串(其中参数由单个空格分隔)或与 Vitest CLI 使用的格式相同的 CLI 参数的字符串数组。它返回一个过滤器和`选项`,你可以稍后将其传递给 `createVitest` 或 `startVitest` 方法。 - -```ts -import { parseCLI } from 'vitest/node' - -parseCLI('vitest ./files.ts --coverage --browser=chrome') -``` - -## Vitest - -Vitest 实例需要当前的测试模式。它可以是以下之一: - -- 运行运行时测试时为 `test` -- 运行基准测试时为 `benchmark` -- 运行类型测试时为 `typecheck` - -### 模式 - -#### test - -测试模式仅会调用 `test` 或 `it` 中的函数,并在遇到 `bench` 时抛出错误。此模式使用配置中的 `include` 和 `exclude` 选项查找测试文件。 - -#### benchmark - -基准测试模式会调用 `bench` 函数,并在遇到 `test` 或 `it` 时抛出错误。此模式使用配置中的 `benchmark.include` 和 `benchmark.exclude` 选项查找基准测试文件。 - -#### typecheck - -类型检查模式不会*运行*测试。它仅分析类型并提供摘要信息。此模式使用配置中的 `typecheck.include` 和 `typecheck.exclude` 选项查找要分析的文件。 - -### start - -你可以使用 `start` 方法运行测试或者基准测试。你还可以传递一个字符串数组以筛选测试文件。 - -### `provide` - -Vitest 提供了 `provide` 方法,它是 `vitest.getRootTestProject().provide` 的简写形式。通过这个方法,你可以将值从主线程传递到测试中。所有值在存储之前都会通过 `structuredClone` 进行检查,但值本身不会被克隆。 - -要在测试中接收值,需要从 `vitest` entrypont 导入 `inject` 方法: - -```ts -import { inject } from 'vitest' -const port = inject('wsPort') // 3000 -``` - -为了提高类型安全性,我们鼓励您增强 `ProvidedContext` 的类型: - -```ts -import { createVitest } from 'vitest/node' - -const vitest = await createVitest('test', { - watch: false, -}) -vitest.provide('wsPort', 3000) - -declare module 'vitest' { - export interface ProvidedContext { - wsPort: number - } -} -``` - -::: warning -在技术上来说,`provide` 是 [`TestProject`](#testproject) 的一个方法,因此它受限于特定的项目。然而,所有项目都从核心项目继承了值,这使得 `vitest.provide` 成为了一种普遍的方式来向测试传递值。 -::: - -::: tip -该方法同样适用于[全局配置文件](/config/#globalsetup),在无法使用公共API的情况下。 - -```js -export default function setup({ provide }) { - provide('wsPort', 3000) -} -``` -::: - -## TestProject 3.0.0 {#testproject} - -- **别名**: `WorkspaceProject` before 3.0.0 - -### name - -这个 name 是由用户指定的唯一字符串,或由 Vitest 解释得出。如果用户未提供名称,Vitest 会尝试在项目根目录加载 `package.json` 文件,并从中获取 `name` 属性作为 name 。若项目中不存在 `package.json` 文件,则 Vitest 默认使用文件夹的名字。对于内联项目,Vitest 使用数字(转换为字符串)作为 name 。 - -::: code-group -```ts [node.js] -import { createVitest } from 'vitest/node' - -const vitest = await createVitest('test') -vitest.projects.map(p => p.name) === [ - '@pkg/server', - 'utils', - '2', - 'custom' -] -``` -```ts [vitest.workspace.js] -export default [ - './packages/server', // package.json 中包含 "@pkg/server" - './utils', // 没有 package.json 文件 - { - // 不要自定义名称 - test: { - pool: 'threads', - }, - }, - { - // 自定义名称 - test: { - name: 'custom', - }, - }, -] -``` -::: - -### vitest - -`vitest` 是指全局的 [`vitest`](#vitest) 进程。 - -### serializedConfig - -所有测试都会接收到的测试配置。Vitest 手动[序列化配置](https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/node/config/serializeConfig.ts),通过移除所有无法序列化的函数和属性来实现。由于这个值在测试和 Node 环境中都可用,因此它从主入口点导出。 - -```ts -import type { SerializedConfig } from 'vitest' - -const config: SerializedConfig = vitest.projects[0].serializedConfig -``` - -### globalConfig - -`vitest` 初始化时所使用的测试配置。如果这是根项目,`globalConfig` 和 `config` 将引用同一个对象。这个配置对于不能在项目级别设置的值非常有用,比如 `coverage` 或 `reporters`。 - -```ts -import type { ResolvedConfig } from 'vitest/node' - -vitest.config === vitest.projects[0].globalConfig -``` - -### config - -这是项目的解析后的测试配置。 - -### vite - -这是项目的 `ViteDevServer`。每个项目都有自己的 Vite 服务器。 - -### browser - -此值仅在测试运行于浏览器中时才会被设置。如果启用了 `browser`,但测试尚未运行,这将为 `undefined`。如果您需要检查项目是否支持浏览器测试,请使用 `project.isBrowserSupported()` 方法。 - -::: warning -这个浏览器API尚在实验阶段,并不遵循语义化(SemVer)版本控制。浏览器API将会独立于其他API进行标准化。 -::: - -### provide - -这是一种在 [`config.provide`](/config/#provide) 字段之外向测试提供自定义值的方法。所有值在存储之前都会通过 [`structuredClone`](https://developer.mozilla.org/en-US/docs/Web/API/Window/structuredClone) 进行验证,但 `providedContext` 中的值本身不会被克隆。 - -::: code-group -```ts [node.js] -import { createVitest } from 'vitest/node' - -const vitest = await createVitest('test') -const project = vitest.projects.find(p => p.name === 'custom') -project.provide('key', 'value') -await vitest.start() -``` -```ts [test.spec.js] -import { inject } from 'vitest' -const value = inject('key') -``` -::: - -这些值可以动态提供。在测试中提供的值将在下一次运行时更新。 - -### getProvidedContext - -这将返回上下文对象。每个项目也会继承由 `vitest.provide` 设置的全局上下文。 - -```ts -import { createVitest } from 'vitest/node' - -const vitest = await createVitest('test') -vitest.provide('global', true) -const project = vitest.projects.find(p => p.name === 'custom') -project.provide('key', 'value') - -// { global: true, key: 'value' } -const context = project.getProvidedContext() -``` - -::: tip -项目上下文的值总是会覆盖全局的值。 -::: - -### createSpecification - -创建一个测试规范,该规范可用于 `vitest.runFiles`。规范将测试文件限定在特定的 `project` 和(可选的)`pool` 中。 - -```ts -import { resolve } from 'node:path/posix' -import { createVitest } from 'vitest/node' - -const vitest = await createVitest('test') -const project = vitest.projects[0] -const specification = project.createSpecification( - resolve('./basic.test.ts'), - 'threads', // 可选覆盖 -) -await vitest.runFiles([specification], true) -``` - -::: warning -`createSpecification` 需要一个绝对文件路径。但是它不会解析文件或检查文件系统上是否存在该文件。 -::: - -### isRootProject - -检查当前项目是否为根项目。我们也可以尝试调用 `vitest.getRootTestProject()` 来获取根项目。 - -根项目通常不运行任何测试,并且不包含在 `vitest.projects` 中,除非我们明确地将根配置包含在它们的工作空间中。 - -根项目的主要目标是设置全局配置。实际上,`rootProject.config` 直接引用了 `rootProject.globalConfig` 和 `vitest.config`。 - -### globTestFiles - -匹配所有测试文件。这个函数返回一个包含常规测试和类型检查测试的对象: - -```ts -interface GlobReturn { - /** - * 测试符合筛选条件的文件。 - */ - testFiles: string[] - /** - * 与筛选器匹配的类型检查测试文件。除非 `typecheck.enabled` 为 `true`,否则将为空。 - */ - typecheckTestFiles: string[] -} -``` - -::: tip -Vitest 使用 [fast-glob](https://www.npmjs.com/package/fast-glob) 来查找测试文件。`test.dir`、`test.root`、`root` 或 `process.cwd()` 定义了 `cwd` 选项。 - -这个方法会查看几个配置选项: - -- `test.include`、`test.exclude` 用于查找常规测试文件; -- `test.includeSource`、`test.exclude` 用于查找源代码中的测试; -- `test.typecheck.include`、`test.typecheck.exclude` 用于查找类型检查测试。 -::: - -### matchesTestGlob - -此方法用于检查文件是否为常规测试文件。它使用与 `globTestFiles` 相同的配置属性进行验证。 - -此方法还接受第二个参数,即源代码。这用于验证文件是否为源代码中的测试。如果我们需要多次为多个项目调用此方法,建议先读取文件一次,然后直接传递源代码。 - -```ts -import { resolve } from 'node:path/posix' -import { createVitest } from 'vitest/node' - -const vitest = await createVitest('test') -const project = vitest.projects[0] - -project.matchesTestGlob(resolve('./basic.test.ts')) // true -project.matchesTestGlob(resolve('./basic.ts')) // false -project.matchesTestGlob(resolve('./basic.ts'), ` -if (import.meta.vitest) { - // ... -} -`) // 如果设置了 `includeSource` 则为 true -``` - -### close - -关闭项目及其所有相关资源。此操作只能调用一次;关闭的承诺会被缓存,直到服务器重新启动。如果再次需要资源,请创建一个新项目。 - -具体来说,这个方法会关闭 Vite 服务器,停止类型检查服务,如果浏览器正在运行则关闭它,删除存放源代码的临时目录,并重置提供的上下文。 diff --git a/api/assert.md b/api/assert.md index 78fcd770..8f484404 100644 --- a/api/assert.md +++ b/api/assert.md @@ -724,11 +724,7 @@ import { assert, test } from 'vitest' test('assert.notInclude', () => { assert.notInclude([1, 2, 3], 4, 'array doesn\'t contain 4') assert.notInclude('foobar', 'baz', 'foobar doesn\'t contain baz') - assert.notInclude( - { foo: 'bar', hello: 'universe' }, - { foo: 'baz' }, - 'object doesn\'t contain property' - ) + assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn\'t contain property') }) ``` @@ -1079,16 +1075,8 @@ test('assert.nestedPropertyVal', () => { import { assert, test } from 'vitest' test('assert.notNestedPropertyVal', () => { - assert.notNestedPropertyVal( - { tea: { green: 'matcha' } }, - 'tea.green', - 'konacha' - ) - assert.notNestedPropertyVal( - { tea: { green: 'matcha' } }, - 'coffee.green', - 'matcha' - ) + assert.notNestedPropertyVal({ tea: { green: 'matcha' } }, 'tea.green', 'konacha') + assert.notNestedPropertyVal({ tea: { green: 'matcha' } }, 'coffee.green', 'matcha') }) ``` @@ -1102,16 +1090,8 @@ test('assert.notNestedPropertyVal', () => { import { assert, test } from 'vitest' test('assert.notNestedPropertyVal', () => { - assert.notNestedPropertyVal( - { tea: { green: 'matcha' } }, - 'tea.green', - 'konacha' - ) - assert.notNestedPropertyVal( - { tea: { green: 'matcha' } }, - 'coffee.green', - 'matcha' - ) + assert.notNestedPropertyVal({ tea: { green: 'matcha' } }, 'tea.green', 'konacha') + assert.notNestedPropertyVal({ tea: { green: 'matcha' } }, 'coffee.green', 'matcha') }) ``` @@ -1125,21 +1105,9 @@ test('assert.notNestedPropertyVal', () => { import { assert, test } from 'vitest' test('assert.notDeepNestedPropertyVal', () => { - assert.notDeepNestedPropertyVal( - { tea: { green: { matcha: 'yum' } } }, - 'tea.green', - { oolong: 'yum' } - ) - assert.notDeepNestedPropertyVal( - { tea: { green: { matcha: 'yum' } } }, - 'tea.green', - { matcha: 'yuck' } - ) - assert.notDeepNestedPropertyVal( - { tea: { green: { matcha: 'yum' } } }, - 'tea.black', - { matcha: 'yum' } - ) + assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' }) + assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' }) + assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' }) }) ``` @@ -1156,15 +1124,7 @@ test('assert.lengthOf', () => { assert.lengthOf([1, 2, 3], 3, 'array has length of 3') assert.lengthOf('foobar', 6, 'string has length of 6') assert.lengthOf(new Set([1, 2, 3]), 3, 'set has size of 3') - assert.lengthOf( - new Map([ - ['a', 1], - ['b', 2], - ['c', 3], - ]), - 3, - 'map has size of 3' - ) + assert.lengthOf(new Map([['a', 1], ['b', 2], ['c', 3]]), 3, 'map has size of 3') }) ``` @@ -1179,21 +1139,9 @@ import { assert, test } from 'vitest' test('assert.hasAnyKeys', () => { assert.hasAnyKeys({ foo: 1, bar: 2, baz: 3 }, ['foo', 'iDontExist', 'baz']) - assert.hasAnyKeys( - { foo: 1, bar: 2, baz: 3 }, - { foo: 30, iDontExist: 99, baz: 1337 } - ) - assert.hasAnyKeys( - new Map([ - [{ foo: 1 }, 'bar'], - ['key', 'value'], - ]), - [{ foo: 1 }, 'key'] - ) - assert.hasAnyKeys(new Set([{ foo: 'bar' }, 'anotherKey']), [ - { foo: 'bar' }, - 'anotherKey', - ]) + assert.hasAnyKeys({ foo: 1, bar: 2, baz: 3 }, { foo: 30, iDontExist: 99, baz: 1337 }) + assert.hasAnyKeys(new Map([[{ foo: 1 }, 'bar'], ['key', 'value'],]), [{ foo: 1 }, 'key']) + assert.hasAnyKeys(new Set([{ foo: 'bar' }, 'anotherKey']), [{ foo: 'bar' }, 'anotherKey']) }) ``` @@ -1208,20 +1156,9 @@ import { assert, test } from 'vitest' test('assert.hasAllKeys', () => { assert.hasAllKeys({ foo: 1, bar: 2, baz: 3 }, ['foo', 'bar', 'baz']) - assert.hasAllKeys( - { foo: 1, bar: 2, baz: 3 }, - { foo: 30, bar: 99, baz: 1337 } - ) - assert.hasAllKeys( - new Map([ - [{ foo: 1 }, 'bar'], - ['key', 'value'], - ]), - [{ foo: 1 }, 'key'] - ) - assert.hasAllKeys( - new Set([{ foo: 'bar' }, 'anotherKey'], [{ foo: 'bar' }, 'anotherKey']) - ) + assert.hasAllKeys({ foo: 1, bar: 2, baz: 3 }, { foo: 30, bar: 99, baz: 1337 }) + assert.hasAllKeys(new Map([[{ foo: 1 }, 'bar'], ['key', 'value'],]), [{ foo: 1 }, 'key']) + assert.hasAllKeys(new Set([{ foo: 'bar' }, 'anotherKey'], [{ foo: 'bar' }, 'anotherKey'])) }) ``` @@ -1238,30 +1175,11 @@ test('assert.containsAllKeys', () => { assert.containsAllKeys({ foo: 1, bar: 2, baz: 3 }, ['foo', 'baz']) assert.containsAllKeys({ foo: 1, bar: 2, baz: 3 }, ['foo', 'bar', 'baz']) assert.containsAllKeys({ foo: 1, bar: 2, baz: 3 }, { foo: 30, baz: 1337 }) - assert.containsAllKeys( - { foo: 1, bar: 2, baz: 3 }, - { foo: 30, bar: 99, baz: 1337 } - ) - assert.containsAllKeys( - new Map([ - [{ foo: 1 }, 'bar'], - ['key', 'value'], - ]), - [{ foo: 1 }] - ) - assert.containsAllKeys( - new Map([ - [{ foo: 1 }, 'bar'], - ['key', 'value'], - ]), - [{ foo: 1 }, 'key'] - ) - assert.containsAllKeys( - new Set([{ foo: 'bar' }, 'anotherKey'], [{ foo: 'bar' }]) - ) - assert.containsAllKeys( - new Set([{ foo: 'bar' }, 'anotherKey'], [{ foo: 'bar' }, 'anotherKey']) - ) + assert.containsAllKeys({ foo: 1, bar: 2, baz: 3 }, { foo: 30, bar: 99, baz: 1337 }) + assert.containsAllKeys(new Map([[{ foo: 1 }, 'bar'], ['key', 'value'],]), [{ foo: 1 }]) + assert.containsAllKeys(new Map([[{ foo: 1 }, 'bar'], ['key', 'value'],]), [{ foo: 1 }, 'key']) + assert.containsAllKeys(new Set([{ foo: 'bar' }, 'anotherKey'], [{ foo: 'bar' }])) + assert.containsAllKeys(new Set([{ foo: 'bar' }, 'anotherKey'], [{ foo: 'bar' }, 'anotherKey'])) }) ``` @@ -1275,25 +1193,10 @@ test('assert.containsAllKeys', () => { import { assert, test } from 'vitest' test('assert.doesNotHaveAnyKeys', () => { - assert.doesNotHaveAnyKeys({ foo: 1, bar: 2, baz: 3 }, [ - 'one', - 'two', - 'example', - ]) - assert.doesNotHaveAnyKeys( - { foo: 1, bar: 2, baz: 3 }, - { one: 1, two: 2, example: 'foo' } - ) - assert.doesNotHaveAnyKeys( - new Map([ - [{ foo: 1 }, 'bar'], - ['key', 'value'], - ]), - [{ one: 'two' }, 'example'] - ) - assert.doesNotHaveAnyKeys( - new Set([{ foo: 'bar' }, 'anotherKey'], [{ one: 'two' }, 'example']) - ) + assert.doesNotHaveAnyKeys({ foo: 1, bar: 2, baz: 3 }, ['one', 'two', 'example',]) + assert.doesNotHaveAnyKeys({ foo: 1, bar: 2, baz: 3 }, { one: 1, two: 2, example: 'foo' }) + assert.doesNotHaveAnyKeys(new Map([[{ foo: 1 }, 'bar'], ['key', 'value'],]), [{ one: 'two' }, 'example']) + assert.doesNotHaveAnyKeys(new Set([{ foo: 'bar' }, 'anotherKey'], [{ one: 'two' }, 'example'])) }) ``` @@ -1307,26 +1210,10 @@ test('assert.doesNotHaveAnyKeys', () => { import { assert, test } from 'vitest' test('assert.hasAnyKeys', () => { - assert.doesNotHaveAnyKeys({ foo: 1, bar: 2, baz: 3 }, [ - 'one', - 'two', - 'example', - ]) - assert.doesNotHaveAnyKeys( - { foo: 1, bar: 2, baz: 3 }, - { one: 1, two: 2, example: 'foo' } - ) - assert.doesNotHaveAnyKeys( - new Map([ - [{ foo: 1 }, 'bar'], - ['key', 'value'], - ]), - [{ one: 'two' }, 'example'] - ) - assert.doesNotHaveAnyKeys(new Set([{ foo: 'bar' }, 'anotherKey']), [ - { one: 'two' }, - 'example', - ]) + assert.doesNotHaveAnyKeys({ foo: 1, bar: 2, baz: 3 }, ['one', 'two', 'example',]) + assert.doesNotHaveAnyKeys({ foo: 1, bar: 2, baz: 3 }, { one: 1, two: 2, example: 'foo' }) + assert.doesNotHaveAnyKeys(new Map([[{ foo: 1 }, 'bar'], ['key', 'value'],]), [{ one: 'two' }, 'example']) + assert.doesNotHaveAnyKeys(new Set([{ foo: 'bar' }, 'anotherKey']), [{ one: 'two' }, 'example',]) }) ``` @@ -1340,38 +1227,12 @@ test('assert.hasAnyKeys', () => { import { assert, test } from 'vitest' test('assert.hasAnyDeepKeys', () => { - assert.hasAnyDeepKeys( - new Map([ - [{ one: 'one' }, 'valueOne'], - [1, 2], - ]), - { one: 'one' } - ) - assert.hasAnyDeepKeys( - new Map([ - [{ one: 'one' }, 'valueOne'], - [1, 2], - ]), - [{ one: 'one' }, { two: 'two' }] - ) - assert.hasAnyDeepKeys( - new Map([ - [{ one: 'one' }, 'valueOne'], - [{ two: 'two' }, 'valueTwo'], - ]), - [{ one: 'one' }, { two: 'two' }] - ) - assert.hasAnyDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), { - one: 'one', - }) - assert.hasAnyDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [ - { one: 'one' }, - { three: 'three' }, - ]) - assert.hasAnyDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [ - { one: 'one' }, - { two: 'two' }, - ]) + assert.hasAnyDeepKeys(new Map([[{ one: 'one' }, 'valueOne'], [1, 2],]), { one: 'one' }) + assert.hasAnyDeepKeys(new Map([[{ one: 'one' }, 'valueOne'], [1, 2],]), [{ one: 'one' }, { two: 'two' }]) + assert.hasAnyDeepKeys(new Map([[{ one: 'one' }, 'valueOne'], [{ two: 'two' }, 'valueTwo'],]), [{ one: 'one' }, { two: 'two' }]) + assert.hasAnyDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), { one: 'one', }) + assert.hasAnyDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [{ one: 'one' }, { three: 'three' },]) + assert.hasAnyDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [{ one: 'one' }, { two: 'two' },]) }) ``` @@ -1385,21 +1246,10 @@ test('assert.hasAnyDeepKeys', () => { import { assert, test } from 'vitest' test('assert.hasAnyDeepKeys', () => { - assert.hasAllDeepKeys(new Map([[{ one: 'one' }, 'valueOne']]), { - one: 'one', - }) - assert.hasAllDeepKeys( - new Map([ - [{ one: 'one' }, 'valueOne'], - [{ two: 'two' }, 'valueTwo'], - ]), - [{ one: 'one' }, { two: 'two' }] - ) + assert.hasAllDeepKeys(new Map([[{ one: 'one' }, 'valueOne']]), { one: 'one', }) + assert.hasAllDeepKeys(new Map([[{ one: 'one' }, 'valueOne'], [{ two: 'two' }, 'valueTwo'],]), [{ one: 'one' }, { two: 'two' }]) assert.hasAllDeepKeys(new Set([{ one: 'one' }]), { one: 'one' }) - assert.hasAllDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [ - { one: 'one' }, - { two: 'two' }, - ]) + assert.hasAllDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [{ one: 'one' }, { two: 'two' },]) }) ``` @@ -1413,27 +1263,10 @@ test('assert.hasAnyDeepKeys', () => { import { assert, test } from 'vitest' test('assert.containsAllDeepKeys', () => { - assert.containsAllDeepKeys( - new Map([ - [{ one: 'one' }, 'valueOne'], - [1, 2], - ]), - { one: 'one' } - ) - assert.containsAllDeepKeys( - new Map([ - [{ one: 'one' }, 'valueOne'], - [{ two: 'two' }, 'valueTwo'], - ]), - [{ one: 'one' }, { two: 'two' }] - ) - assert.containsAllDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), { - one: 'one', - }) - assert.containsAllDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [ - { one: 'one' }, - { two: 'two' }, - ]) + assert.containsAllDeepKeys(new Map([[{ one: 'one' }, 'valueOne'], [1, 2],]), { one: 'one' }) + assert.containsAllDeepKeys(new Map([[{ one: 'one' }, 'valueOne'], [{ two: 'two' }, 'valueTwo'],]), [{ one: 'one' }, { two: 'two' }]) + assert.containsAllDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), { one: 'one', }) + assert.containsAllDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [{ one: 'one' }, { two: 'two' },]) }) ``` @@ -1447,27 +1280,10 @@ test('assert.containsAllDeepKeys', () => { import { assert, test } from 'vitest' test('assert.doesNotHaveAnyDeepKeys', () => { - assert.doesNotHaveAnyDeepKeys( - new Map([ - [{ one: 'one' }, 'valueOne'], - [1, 2], - ]), - { thisDoesNot: 'exist' } - ) - assert.doesNotHaveAnyDeepKeys( - new Map([ - [{ one: 'one' }, 'valueOne'], - [{ two: 'two' }, 'valueTwo'], - ]), - [{ twenty: 'twenty' }, { fifty: 'fifty' }] - ) - assert.doesNotHaveAnyDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), { - twenty: 'twenty', - }) - assert.doesNotHaveAnyDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [ - { twenty: 'twenty' }, - { fifty: 'fifty' }, - ]) + assert.doesNotHaveAnyDeepKeys(new Map([[{ one: 'one' }, 'valueOne'], [1, 2],]), { thisDoesNot: 'exist' }) + assert.doesNotHaveAnyDeepKeys(new Map([[{ one: 'one' }, 'valueOne'], [{ two: 'two' }, 'valueTwo'],]), [{ twenty: 'twenty' }, { fifty: 'fifty' }]) + assert.doesNotHaveAnyDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), { twenty: 'twenty', }) + assert.doesNotHaveAnyDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [{ twenty: 'twenty' }, { fifty: 'fifty' },]) }) ``` @@ -1481,27 +1297,10 @@ test('assert.doesNotHaveAnyDeepKeys', () => { import { assert, test } from 'vitest' test('assert.doesNotHaveAllDeepKeys', () => { - assert.doesNotHaveAllDeepKeys( - new Map([ - [{ one: 'one' }, 'valueOne'], - [1, 2], - ]), - { thisDoesNot: 'exist' } - ) - assert.doesNotHaveAllDeepKeys( - new Map([ - [{ one: 'one' }, 'valueOne'], - [{ two: 'two' }, 'valueTwo'], - ]), - [{ twenty: 'twenty' }, { one: 'one' }] - ) - assert.doesNotHaveAllDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), { - twenty: 'twenty', - }) - assert.doesNotHaveAllDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [ - { one: 'one' }, - { fifty: 'fifty' }, - ]) + assert.doesNotHaveAllDeepKeys(new Map([[{ one: 'one' }, 'valueOne'], [1, 2],]), { thisDoesNot: 'exist' }) + assert.doesNotHaveAllDeepKeys(new Map([[{ one: 'one' }, 'valueOne'], [{ two: 'two' }, 'valueTwo'],]), [{ twenty: 'twenty' }, { one: 'one' }]) + assert.doesNotHaveAllDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), { twenty: 'twenty', }) + assert.doesNotHaveAllDeepKeys(new Set([{ one: 'one' }, { two: 'two' }]), [{ one: 'one' }, { fifty: 'fifty' },]) }) ``` @@ -1524,26 +1323,10 @@ test('assert.throws', () => { assert.throws(fn, /Error thrown must have a msg that matches this/) assert.throws(fn, ReferenceError) assert.throws(fn, errorInstance) - assert.throws( - fn, - ReferenceError, - 'Error thrown must be a ReferenceError and have this msg' - ) - assert.throws( - fn, - errorInstance, - 'Error thrown must be the same errorInstance and have this msg' - ) - assert.throws( - fn, - ReferenceError, - /Error thrown must be a ReferenceError and match this/ - ) - assert.throws( - fn, - errorInstance, - /Error thrown must be the same errorInstance and match this/ - ) + assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg') + assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg') + assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/) + assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/) }) ``` @@ -1636,11 +1419,7 @@ test('assert.sameMembers', () => { import { assert, test } from 'vitest' test('assert.sameDeepMembers', () => { - assert.sameDeepMembers( - [{ a: 1 }, { b: 2 }, { c: 3 }], - [{ b: 2 }, { a: 1 }, { c: 3 }], - 'same deep members' - ) + assert.sameDeepMembers([{ a: 1 }, { b: 2 }, { c: 3 }], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members') }) ``` @@ -1654,11 +1433,7 @@ test('assert.sameDeepMembers', () => { import { assert, test } from 'vitest' test('assert.sameDeepMembers', () => { - assert.sameDeepMembers( - [{ a: 1 }, { b: 2 }, { c: 3 }], - [{ b: 2 }, { a: 1 }, { c: 3 }], - 'same deep members' - ) + assert.sameDeepMembers([{ a: 1 }, { b: 2 }, { c: 3 }], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members') }) ``` @@ -1686,11 +1461,7 @@ test('assert.sameOrderedMembers', () => { import { assert, test } from 'vitest' test('assert.notSameOrderedMembers', () => { - assert.notSameOrderedMembers( - [1, 2, 3], - [2, 1, 3], - 'not same ordered members' - ) + assert.notSameOrderedMembers([1, 2, 3], [2, 1, 3], 'not same ordered members') }) ``` @@ -1704,11 +1475,7 @@ test('assert.notSameOrderedMembers', () => { import { assert, test } from 'vitest' test('assert.sameDeepOrderedMembers', () => { - assert.sameDeepOrderedMembers( - [{ a: 1 }, { b: 2 }, { c: 3 }], - [{ a: 1 }, { b: 2 }, { c: 3 }], - 'same deep ordered members' - ) + assert.sameDeepOrderedMembers([{ a: 1 }, { b: 2 }, { c: 3 }], [{ a: 1 }, { b: 2 }, { c: 3 }], 'same deep ordered members') }) ``` @@ -1722,16 +1489,8 @@ test('assert.sameDeepOrderedMembers', () => { import { assert, test } from 'vitest' test('assert.notSameDeepOrderedMembers', () => { - assert.notSameDeepOrderedMembers( - [{ a: 1 }, { b: 2 }, { c: 3 }], - [{ a: 1 }, { b: 2 }, { z: 5 }], - 'not same deep ordered members' - ) - assert.notSameDeepOrderedMembers( - [{ a: 1 }, { b: 2 }, { c: 3 }], - [{ b: 2 }, { a: 1 }, { c: 3 }], - 'not same deep ordered members' - ) + assert.notSameDeepOrderedMembers([{ a: 1 }, { b: 2 }, { c: 3 }], [{ a: 1 }, { b: 2 }, { z: 5 }], 'not same deep ordered members') + assert.notSameDeepOrderedMembers([{ a: 1 }, { b: 2 }, { c: 3 }], [{ b: 2 }, { a: 1 }, { c: 3 }], 'not same deep ordered members') }) ``` @@ -1773,11 +1532,7 @@ test('assert.notIncludeMembers', () => { import { assert, test } from 'vitest' test('assert.includeDeepMembers', () => { - assert.includeDeepMembers( - [{ a: 1 }, { b: 2 }, { c: 3 }], - [{ b: 2 }, { a: 1 }, { b: 2 }], - 'include deep members' - ) + assert.includeDeepMembers([{ a: 1 }, { b: 2 }, { c: 3 }], [{ b: 2 }, { a: 1 }, { b: 2 }], 'include deep members') }) ``` @@ -1791,11 +1546,7 @@ test('assert.includeDeepMembers', () => { import { assert, test } from 'vitest' test('assert.notIncludeDeepMembers', () => { - assert.notIncludeDeepMembers( - [{ a: 1 }, { b: 2 }, { c: 3 }], - [{ b: 2 }, { f: 5 }], - 'not include deep members' - ) + assert.notIncludeDeepMembers([{ a: 1 }, { b: 2 }, { c: 3 }], [{ b: 2 }, { f: 5 }], 'not include deep members') }) ``` @@ -1823,16 +1574,8 @@ test('assert.includeOrderedMembers', () => { import { assert, test } from 'vitest' test('assert.notIncludeOrderedMembers', () => { - assert.notIncludeOrderedMembers( - [1, 2, 3], - [2, 1], - 'not include ordered members' - ) - assert.notIncludeOrderedMembers( - [1, 2, 3], - [2, 3], - 'not include ordered members' - ) + assert.notIncludeOrderedMembers([1, 2, 3], [2, 1], 'not include ordered members') + assert.notIncludeOrderedMembers([1, 2, 3], [2, 3], 'not include ordered members') }) ``` @@ -1846,11 +1589,7 @@ test('assert.notIncludeOrderedMembers', () => { import { assert, test } from 'vitest' test('assert.includeDeepOrderedMembers', () => { - assert.includeDeepOrderedMembers( - [{ a: 1 }, { b: 2 }, { c: 3 }], - [{ a: 1 }, { b: 2 }], - 'include deep ordered members' - ) + assert.includeDeepOrderedMembers([{ a: 1 }, { b: 2 }, { c: 3 }], [{ a: 1 }, { b: 2 }], 'include deep ordered members') }) ``` @@ -1864,21 +1603,9 @@ test('assert.includeDeepOrderedMembers', () => { import { assert, test } from 'vitest' test('assert.includeDeepOrderedMembers', () => { - assert.notIncludeDeepOrderedMembers( - [{ a: 1 }, { b: 2 }, { c: 3 }], - [{ a: 1 }, { f: 5 }], - 'not include deep ordered members' - ) - assert.notIncludeDeepOrderedMembers( - [{ a: 1 }, { b: 2 }, { c: 3 }], - [{ b: 2 }, { a: 1 }], - 'not include deep ordered members' - ) - assert.notIncludeDeepOrderedMembers( - [{ a: 1 }, { b: 2 }, { c: 3 }], - [{ b: 2 }, { c: 3 }], - 'not include deep ordered members' - ) + assert.notIncludeDeepOrderedMembers([{ a: 1 }, { b: 2 }, { c: 3 }], [{ a: 1 }, { f: 5 }], 'not include deep ordered members') + assert.notIncludeDeepOrderedMembers([{ a: 1 }, { b: 2 }, { c: 3 }], [{ b: 2 }, { a: 1 }], 'not include deep ordered members') + assert.notIncludeDeepOrderedMembers([{ a: 1 }, { b: 2 }, { c: 3 }], [{ b: 2 }, { c: 3 }], 'not include deep ordered members') }) ``` @@ -1907,9 +1634,7 @@ import { assert, test } from 'vitest' test('assert.changes', () => { const obj = { val: 10 } - function fn() { - obj.val = 22 - } + function fn() { obj.val = 22 }; assert.changes(fn, obj, 'val') }) ``` @@ -1925,9 +1650,7 @@ import { assert, test } from 'vitest' test('assert.changesBy', () => { const obj = { val: 10 } - function fn() { - obj.val += 2 - } + function fn() { obj.val += 2 }; assert.changesBy(fn, obj, 'val', 2) }) ``` @@ -1943,9 +1666,7 @@ import { assert, test } from 'vitest' test('assert.doesNotChange', () => { const obj = { val: 10 } - function fn() { - obj.val += 2 - } + function fn() { obj.val += 2 }; assert.doesNotChange(fn, obj, 'val', 2) }) ``` @@ -1961,9 +1682,7 @@ import { assert, test } from 'vitest' test('assert.changesButNotBy', () => { const obj = { val: 10 } - function fn() { - obj.val += 10 - } + function fn() { obj.val += 10 }; assert.changesButNotBy(fn, obj, 'val', 5) }) ``` @@ -1979,9 +1698,7 @@ import { assert, test } from 'vitest' test('assert.increases', () => { const obj = { val: 10 } - function fn() { - obj.val = 13 - } + function fn() { obj.val = 13 }; assert.increases(fn, obj, 'val') }) ``` @@ -2013,9 +1730,7 @@ import { assert, test } from 'vitest' test('assert.doesNotIncrease', () => { const obj = { val: 10 } - function fn() { - obj.val = 8 - } + function fn() { obj.val = 8 } assert.doesNotIncrease(fn, obj, 'val') }) ``` @@ -2031,9 +1746,7 @@ import { assert, test } from 'vitest' test('assert.increasesButNotBy', () => { const obj = { val: 10 } - function fn() { - obj.val += 15 - } + function fn() { obj.val += 15 }; assert.increasesButNotBy(fn, obj, 'val', 10) }) ``` @@ -2049,9 +1762,7 @@ import { assert, test } from 'vitest' test('assert.decreases', () => { const obj = { val: 10 } - function fn() { - obj.val = 5 - } + function fn() { obj.val = 5 }; assert.decreases(fn, obj, 'val') }) ``` @@ -2067,9 +1778,7 @@ import { assert, test } from 'vitest' test('assert.decreasesBy', () => { const obj = { val: 10 } - function fn() { - obj.val -= 5 - } + function fn() { obj.val -= 5 }; assert.decreasesBy(fn, obj, 'val', 5) }) ``` @@ -2085,9 +1794,7 @@ import { assert, test } from 'vitest' test('assert.doesNotDecrease', () => { const obj = { val: 10 } - function fn() { - obj.val = 15 - } + function fn() { obj.val = 15 } assert.doesNotDecrease(fn, obj, 'val') }) ``` @@ -2103,9 +1810,7 @@ import { assert, test } from 'vitest' test('assert.doesNotDecreaseBy', () => { const obj = { val: 10 } - function fn() { - obj.val = 5 - } + function fn() { obj.val = 5 }; assert.doesNotDecreaseBy(fn, obj, 'val', 1) }) ``` @@ -2121,9 +1826,7 @@ import { assert, test } from 'vitest' test('assert.decreasesButNotBy', () => { const obj = { val: 10 } - function fn() { - obj.val = 5 - } + function fn() { obj.val = 5 }; assert.decreasesButNotBy(fn, obj, 'val', 1) }) ``` diff --git a/api/expect.md b/api/expect.md index 29ce3970..708dcf1e 100644 --- a/api/expect.md +++ b/api/expect.md @@ -31,7 +31,7 @@ expect(input).to.equal(2) // chai API expect(input).toBe(2) // jest API ``` -从技术上讲,这个示例没有使用 [`test`](/api/#test) 函数,因此在控制台中你将看到 Nodejs 错误而不是 Vitest 输出。 要了解更多关于 `test` 的信息,请阅读[测试 API 参考](/api/)。 +从技术上讲,这个示例没有使用 [`test`](/api/#test) 函数,因此在控制台中你将看到 Nodejs 错误而不是 Vitest 输出。 要了解更多关于 `test` 的信息,请阅读[Test API](/api/)。 此外,`expect` 可以静态地使用来访问匹配器函数,稍后将会介绍。 @@ -1335,7 +1335,7 @@ test('spy function returns bananas on second call', async () => { - **类型:** `(predicate: (value: any) => boolean) => Awaitable` -该断言检查一个值是否满足「某个谓词/certain predicate」。 +该断言检查一个值是否满足某个谓词(certain predicate)。 ```ts import { describe, expect, it } from 'vitest' @@ -1746,7 +1746,7 @@ declare module 'vitest' { ::: :::tip -如果想了解更多信息,请查看 [扩展断言 (Matchers) 指南](/guide/extending-matchers)。 +如果想了解更多信息,请查看 [扩展断言](/guide/extending-matchers)。 ::: ## expect.addEqualityTesters {#expect-addequalitytesters} diff --git a/api/index.md b/api/index.md index fb1ad821..466632cd 100644 --- a/api/index.md +++ b/api/index.md @@ -35,7 +35,7 @@ interface TestOptions { 当测试函数返回一个 promise 时,运行器会等待它解析结束收集异步的结果。如果 promise 被拒绝,测试就会失败。 ::: tip -在 Jest 中,`TestFunction` 也可以是 `(done: DoneCallback) => void` 类型。如果使用这种形式,测试将在调用 `done` 之前不会结束。也可以使用 `async` 函数来实现相同的效果,请参阅[迁移指南中的回调完成部分](/guide/migration#回调完成)。 +在 Jest 中,`TestFunction` 也可以是 `(done: DoneCallback) => void` 类型。如果使用这种形式,测试将在调用 `done` 之前不会结束。也可以使用 `async` 函数来实现相同的效果,请参阅 [迁移指南中的回调完成部分](/guide/migration.html#done-callback)。 ::: @@ -108,7 +108,7 @@ test('heavy test', { skip: true, timeout: 10_000 }, () => { `test` 定义了一组相关的期望。 它接收测试名称和保存测试期望的函数。 -或者,我们可以提供超时(以毫秒为单位)来指定终止前等待的时间。 默认为 5 秒,可以通过 [testTimeout](/config/#testtimeout) 进行全局配置 +或者,我们可以提供超时(以毫秒为单位)来指定终止前等待的时间。 默认为 5 秒,可以通过 [testTimeout](/config/#testtimeout) 进行全局配置。 ```ts import { expect, test } from 'vitest' @@ -123,7 +123,7 @@ test('should work as expected', () => { - **类型:** `>(fixtures: Fixtures): TestAPI` - **别名:** `it.extend` -使用 `test.extend` 来使用自定义的 fixtures 扩展测试上下文。这将返回一个新的 `test`,它也是可扩展的,因此可以根据需要扩展更多的 fixtures 或覆盖现有的 fixtures。有关更多信息,请参阅[扩展测试上下文](/guide/test-context.html#test-extend)。 +使用 `test.extend` 来使用自定义的 fixtures 扩展测试上下文。这将返回一个新的 `test`,它也是可扩展的,因此可以根据需要扩展更多的 fixtures 或覆盖现有的 fixtures。有关更多信息,请参阅 [扩展测试上下文](/guide/test-context.html#test-extend)。 ```ts import { expect, test } from 'vitest' @@ -176,7 +176,7 @@ test('skipped test', (context) => { }) ``` -自 Vitest 3.1 起,如果你无法提前确定是否跳过,可以把条件直接作为第一个参数传给 `skip 方法: +自 Vitest 3.1 起,如果你无法提前确定是否跳过,可以把条件直接作为第一个参数传给 `skip` 方法: ```ts import { assert, test } from 'vitest' @@ -206,7 +206,7 @@ test.skipIf(isDev)('prod only test', () => { ``` ::: warning -在将 Vitest 用作[类型检查器](/guide/testing-types)时,不能使用此语法。 +在将 Vitest 用作 [类型检查器](/guide/testing-types) 时,不能使用此语法。 ::: ### test.runIf @@ -227,7 +227,7 @@ test.runIf(isDev)('dev only test', () => { ``` ::: warning -在将 Vitest 用作[类型检查器](/guide/testing-types)时,不能使用此语法。 +在将 Vitest 用作 [类型检查器](/guide/testing-types) 时,不能使用此语法。 ::: ### test.only @@ -248,7 +248,7 @@ test.only('test', () => { }) ``` -有时,只运行某个文件中的 "测试",而忽略整个 测试套件 中的所有其他测试是非常有用的,因为这些测试会污染输出。 +有时,只运行某个文件中的 "测试",而忽略整个测试套件中的所有其他测试是非常有用的,因为这些测试会污染输出。 为此,请使用包含相关测试的特定文件运行 `vitest`。 @@ -289,7 +289,7 @@ test.only.concurrent(/* ... */) // or test.concurrent.only(/* ... */) test.todo.concurrent(/* ... */) // or test.concurrent.todo(/* ... */) ``` -运行并发测试时,快照和断言必须使用本地[测试上下文](/guide/test-context.md)中的 `expect`,以确保检测到正确的测试。 +运行并发测试时,快照和断言必须使用本地 [测试上下文](/guide/test-context.md) 中的 `expect`,以确保检测到正确的测试。 ```ts test.concurrent('test 1', async ({ expect }) => { @@ -301,12 +301,13 @@ test.concurrent('test 2', async ({ expect }) => { ``` ::: warning -在将 Vitest 用作[类型检查器](/guide/testing-types)时,不能使用此语法。 +在将 Vitest 用作 [类型检查器](/guide/testing-types) 时,不能使用此语法。 ::: ### test.sequential - **类型:** `(name: string | Function, fn: TestFunction, timeout?: number) => void` +- **别名:** `it.sequential` `test.sequential` 标记一个测试为顺序测试。如果要在 `describe.concurrent` 中或使用 `--sequence.concurrent` 命令选项按顺序运行测试,这一点非常有用。 @@ -314,35 +315,19 @@ test.concurrent('test 2', async ({ expect }) => { import { describe, test } from 'vitest' // 使用配置选项 `{ sequence: { concurrent: true } }` -test('concurrent test 1', async () => { - /* ... */ -}) -test('concurrent test 2', async () => { - /* ... */ -}) +test('concurrent test 1', async () => { /* ... */ }) +test('concurrent test 2', async () => { /* ... */ }) -test.sequential('sequential test 1', async () => { - /* ... */ -}) -test.sequential('sequential test 2', async () => { - /* ... */ -}) +test.sequential('sequential test 1', async () => { /* ... */ }) +test.sequential('sequential test 2', async () => { /* ... */ }) // 在并发套件中 describe.concurrent('suite', () => { - test('concurrent test 1', async () => { - /* ... */ - }) - test('concurrent test 2', async () => { - /* ... */ - }) + test('concurrent test 1', async () => { /* ... */ }) + test('concurrent test 2', async () => { /* ... */ }) - test.sequential('sequential test 1', async () => { - /* ... */ - }) - test.sequential('sequential test 2', async () => { - /* ... */ - }) + test.sequential('sequential test 1', async () => { /* ... */ }) + test.sequential('sequential test 2', async () => { /* ... */ }) }) ``` @@ -360,7 +345,6 @@ test.todo('unimplemented test') ### test.fails -- **类型:** `(name: string | Function, fn: TestFunction, timeout?: number) => void` - **别名:** `it.fails` 使用 `test.fails` 明确表示断言将失败。 @@ -377,7 +361,7 @@ test.fails('fail test', async () => { ``` ::: warning -在将 Vitest 用作[类型检查器](/guide/testing-types)时,不能使用此语法。 +在将 Vitest 用作 [类型检查器](/guide/testing-types) 时,不能使用此语法。 ::: ### test.each @@ -487,7 +471,7 @@ Vitest 使用 chai `format` 方法处理 `$values`。如果数值太短,可以 ::: ::: warning -在将 Vitest 用作[类型检查器](/guide/testing-types)时,不能使用此语法。 +在将 Vitest 用作 [类型检查器](/guide/testing-types) 时,不能使用此语法。 ::: ### test.for @@ -504,8 +488,8 @@ test.each([ [1, 1, 2], [1, 2, 3], [2, 1, 3], -])('add(%i, %i) -> %i', (a, b, expected) => { // [!code --] +])('add(%i, %i) -> %i', (a, b, expected) => { expect(a + b).toBe(expected) }) @@ -514,8 +498,8 @@ test.for([ [1, 1, 2], [1, 2, 3], [2, 1, 3], -])('add(%i, %i) -> %i', ([a, b, expected]) => { // [!code ++] +])('add(%i, %i) -> %i', ([a, b, expected]) => { expect(a + b).toBe(expected) }) ``` @@ -856,6 +840,7 @@ describe('numberToCurrency', () => { ### describe.skip - **类型:** `(name: string | Function, fn: TestFunction, options?: number | TestOptions) => void` +- **别名:** `suite.skip` 在套件中使用 `describe.skip` 可避免运行特定的 describe 块。 @@ -873,6 +858,7 @@ describe.skip('skipped suite', () => { ### describe.skipIf - **类型:** `(condition: any) => void` +- **别名:** `suite.skipIf` 在某些情况下,可能会在不同的环境下多次运行套件,其中一些测试套件可能是特定于环境的。可以使用 `describe.skipIf` 来跳过条件为真时的套件,而不是使用 `if` 来封装套件。 @@ -893,6 +879,7 @@ describe.skipIf(isDev)('prod only test suite', () => { ### describe.runIf - **类型:** `(condition: any) => void` +- **别名:** `suite.runIf` 与 [describe.skipIf](#describe-skipif) 相反。 @@ -931,11 +918,9 @@ describe('other suite', () => { }) ``` -为了做到这一点,请使用包含相关测试的特定文件来运行 `vitest`。 - 有时,只运行某个文件中的测试套件,而忽略整个测试套件中的所有其他测试是非常有用的,因为这些测试会污染输出。 -要做到这一点,请在包含相关测试的特定文件中运行 `vitest`。 +为了做到这一点,请使用包含相关测试的特定文件来运行 `vitest`。 ``` # vitest interesting.test.ts @@ -978,7 +963,7 @@ describe.only.concurrent(/* ... */) // 或 describe.concurrent.only(/* ... */) describe.todo.concurrent(/* ... */) // 或 describe.concurrent.todo(/* ... */) ``` -运行并发测试时,快照和断言必须使用本地[测试上下文](/guide/test-context.md)中的 `expect` ,以确保检测到正确的测试。 +运行并发测试时,快照和断言必须使用本地 [测试上下文](/guide/test-context.md) 中的 `expect` ,以确保检测到正确的测试。 ```ts describe.concurrent('suite', () => { @@ -992,12 +977,13 @@ describe.concurrent('suite', () => { ``` ::: warning -在将 Vitest 用作[类型检查器](/guide/testing-types)时,不能使用此语法。 +在将 Vitest 用作 [类型检查器](/guide/testing-types) 时,不能使用此语法。 ::: ### describe.sequential - **类型:** `(name: string | Function, fn: TestFunction, options?: number | TestOptions) => void` +- **别名:** `suite.sequential` 测试套件中的 `describe.sequential` 会将每个测试标记为顺序测试。如果需要在 `describe.concurrent` 中或使用 `--sequence.concurrent` 命令选项按顺序运行测试,这一点非常有用。 @@ -1005,20 +991,12 @@ describe.concurrent('suite', () => { import { describe, test } from 'vitest' describe.concurrent('suite', () => { - test('concurrent test 1', async () => { - /* ... */ - }) - test('concurrent test 2', async () => { - /* ... */ - }) + test('concurrent test 1', async () => { /* ... */ }) + test('concurrent test 2', async () => { /* ... */ }) describe.sequential('', () => { - test('sequential test 1', async () => { - /* ... */ - }) - test('sequential test 2', async () => { - /* ... */ - }) + test('sequential test 1', async () => { /* ... */ }) + test('sequential test 2', async () => { /* ... */ }) }) }) ``` @@ -1026,6 +1004,7 @@ describe.concurrent('suite', () => { ### describe.shuffle - **类型:** `(name: string | Function, fn: TestFunction, options?: number | TestOptions) => void` +- **别名:** `suite.shuffle` Vitest 通过 CLI 标志 [`--sequence.shuffle`](/guide/cli) 或配置选项 [`sequence.shuffle`](/config/#sequence-shuffle),提供了一种以随机顺序运行所有测试的方法,但如果只想让测试套件的一部分以随机顺序运行测试,可以用这个标志来标记它。 @@ -1034,48 +1013,35 @@ import { describe, test } from 'vitest' // 或 `describe('suite', { shuffle: true }, ...)` describe.shuffle('suite', () => { - test('random test 1', async () => { - /* ... */ - }) - test('random test 2', async () => { - /* ... */ - }) - test('random test 3', async () => { - /* ... */ - }) + test('random test 1', async () => { /* ... */ }) + test('random test 2', async () => { /* ... */ }) + test('random test 3', async () => { /* ... */ }) // `shuffle` 是继承的 describe('still random', () => { - test('random 4.1', async () => { - /* ... */ - }) - test('random 4.2', async () => { - /* ... */ - }) + test('random 4.1', async () => { /* ... */ }) + test('random 4.2', async () => { /* ... */ }) }) // 禁用内部的 shuffle describe('not random', { shuffle: false }, () => { - test('in order 5.1', async () => { - /* ... */ - }) - test('in order 5.2', async () => { - /* ... */ - }) + test('in order 5.1', async () => { /* ... */ }) + test('in order 5.2', async () => { /* ... */ }) }) }) // 顺序取决于配置中的 `sequence.seed` 选项(默认为 `Date.now()`) ``` -`.skip`、`.only`和`.todo`适用于随机测试套件。 +`.skip`、 `.only` 和 `.todo` 适用于随机测试套件。 ::: warning -在将 Vitest 用作[类型检查器](/guide/testing-types)时,不能使用此语法。 +在将 Vitest 用作 [类型检查器](/guide/testing-types) 时,不能使用此语法。 ::: ### describe.todo - **类型:** `(name: string | Function) => void` +- **别名:** `suite.todo` 使用 `describe.todo` 来暂存待以后实施的套件。测试报告中会显示一个条目,这样就能知道还有多少测试需要执行。 @@ -1087,6 +1053,7 @@ describe.todo('unimplemented suite') ### describe.each - **类型:** `(cases: ReadonlyArray, ...args: any[]): (name: string | Function, fn: (...args: T[]) => void, options?: number | TestOptions) => void` +- **别名:** `suite.each` ::: tip 虽然 `describe.each` 是为了兼容 Jest 提供的, @@ -1140,7 +1107,7 @@ describe.each` ``` ::: warning -在将 Vitest 用作[类型检查器](/guide/testing-types)时,不能使用此语法。 +在将 Vitest 用作 [类型检查器](/guide/testing-types) 时,不能使用此语法。 ::: ### describe.for diff --git a/api/vi.md b/api/vi.md index a2860833..7cb7772a 100644 --- a/api/vi.md +++ b/api/vi.md @@ -4,7 +4,7 @@ outline: deep # Vi -Vitest 通过其 `vi` 辅助工具提供实用功能来帮助你。可以全局访问它(当启用 [globals 配置](/config/#globals) 时),也可以直接从 `vitest` 中导入: +Vitest 通过 `vi` 工具函数提供实用功能。可以全局访问它(当启用 [globals 配置](/config/#globals) 时),也可以直接从 `vitest` 中导入: ```js import { vi } from 'vitest' @@ -452,7 +452,7 @@ expect(Cart).toHaveBeenCalled() function mockObject(value: T): MaybeMockedDeep ``` -它与 `vi.mock()` 模拟模块相同,深层模拟给定对象的属性和方法。详见[自动模拟](/guide/mocking.html#automocking-algorithm)。 +它与 `vi.mock()` 模拟模块相同,深层模拟给定对象的属性和方法。详见 [自动模拟](/guide/mocking.html#automocking-algorithm)。 ```ts const original = { @@ -745,7 +745,7 @@ window.innerWidth = 100 function unstubAllGlobals(): Vitest ``` -恢复 `globalThis` / `global`(和 `window` / `top` / `self` / `parent `,如果我们使用的是 `jsdom` 或 `happy-dom` 环境)上所有被 `vi.stubGlobal` 更改过的全局值。第一次调用时,Vitest 会记住并保存原始值,直到再次调用 `unstubAllGlobals`。 +恢复 `globalThis` / `global`(和 `window` / `top` / `self` / `parent`,如果我们使用的是 `jsdom` 或 `happy-dom` 环境)上所有被 `vi.stubGlobal` 更改过的全局值。第一次调用时,Vitest 会记住并保存原始值,直到再次调用 `unstubAllGlobals`。 ```ts import { vi } from 'vitest' @@ -1006,7 +1006,7 @@ function setSystemTime(date: string | number | Date): Vitest 如果启用了伪计时器,此方法将模拟用户更改系统时钟(将影响与日期相关的 API,如 `hrtime` 、`performance.now` 或 `new Date()` ),但不会触发任何计时器。如果未启用假定时器,该方法将仅模拟 `Date.*` 调用。 -如果我们需要测试任何依赖于当前日期的内容 -- 例如在代码中调用 [luxon](https://github.com/moment/luxon/) --则非常有用。 +适用于需要测试依赖当前日期的场景,例如代码中的 [Luxon](https://github.com/moment/luxon/) 库调用。 接受与 `Date` 相同的字符串和数字参数。 @@ -1044,7 +1044,7 @@ function useFakeTimers(config?: FakeTimerInstallOpts): Vitest function isFakeTimers(): boolean ``` -如果启用了假计时器,则返回 `true` 。 +如果启用了模拟计时器,则返回 `true` 。 ### vi.useRealTimers diff --git a/config/index.md b/config/index.md index 9acd9040..ee5b3e25 100644 --- a/config/index.md +++ b/config/index.md @@ -10,9 +10,9 @@ outline: deep - 向 CLI 传递 `--config` 选项,例如 `vitest --config ./path/to/vitest.config.ts`。 - 使用 `process.env.VITEST` 或在 `defineConfig` 上的 `mode` 属性(如果没有用 `--mode` 覆盖,默认设置为 `test`/`benchmark`)来在 `vite.config.ts` 中有条件地应用不同的配置。请注意,像任何其他环境变量一样,`VITEST` 也会在测试中的 `import.meta.env` 上暴露出来。 -要配置 Vitest 本身,请在我们的 Vite 配置中添加 `test` 属性。如果我们是从 `vite` 本身导入 `defineConfig`,我们还需要在配置文件顶部使用[三斜杠指令](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-)添加对 Vitest 类型引用。 +要配置 Vitest 本身,请在我们的 Vite 配置中添加 `test` 属性。如果我们是从 `vite` 本身导入 `defineConfig`,我们还需要在配置文件顶部使用 [三斜杠指令](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-) 添加对 Vitest 类型引用。 -::: details Open Config Examples +::: details 打开配置示例 使用 `vite` 中的 `defineConfig` 时使用以下步骤: ```ts [vite.config.js] @@ -192,7 +192,7 @@ Vite-Node 调试器选项。 这些选项支持在 `node_modules` 中编写的包名称或在 [`deps.moduleDirectories`](#deps-moduledirectories) 中指定的包名称。例如,位于 `packages/some-name` 内的包`@company/some-name` 应指定为 `some-name`,并且 `packages` 应包含在 `deps.moduleDirectories` 中。基本上,Vitest 总是检查文件路径,而不是实际的包名称。 -如果成功匹配,Vitest 会在 _file path_ 上调用它,而不是包名称。 +如果使用正则匹配,Vitest 会在 _file path_ 上调用它,而不是包名称。 #### server.deps.inline @@ -228,7 +228,7 @@ Vite 将处理内联模块。这可能有助于处理以 ESM 格式传送 `.js` #### deps.optimizer {#deps-optimizer} - **类型:** `{ ssr?, client? }` -- **参考:** [Dep Optimization Options](https://vitejs.dev/config/dep-optimization-options.html) +- **参考:** [依赖优化选项](https://vitejs.dev/config/dep-optimization-options.html) 启用依赖优化。如果你有很多测试,这可能会提高它们的性能。 @@ -368,9 +368,9 @@ export default defineConfig({ ### runner - **类型**: `VitestRunnerConstructor` -- **默认值**: `node`, when running tests, or `benchmark`, when running benchmarks +- **默认值**: 运行测试时为`node`,运行基准测试时为 `benchmark` -自定义测试运行程序的路径。这是一项高级功能,应与自定义库运行器一起使用。你可以在 [文档](/advanced/runner) 中阅读更多相关信息。 +自定义测试运行器的路径。这是一项高级功能,应与自定义库运行器一起使用。你可以在 [文档](/advanced/runner) 中阅读更多相关信息。 ### benchmark @@ -445,12 +445,12 @@ vitest bench --compare main.json 在测试内部运行时定义自定义别名。它们将与来自 `resolve.alias` 的别名合并。 ::: warning -Vitest 使用 Vite SSR 基元来运行测试,这有[一定的缺陷](https://vitejs.dev/guide/ssr.html#ssr-externals)。 +Vitest 使用 Vite SSR 基元来运行测试,这有 [一定的缺陷](https://vitejs.dev/guide/ssr.html#ssr-externals)。 -1. 别名只影响由[inlined](#server-deps-inline)模块直接用`import`关键字导入的模块(默认情况下所有源代码都是内联的)。 +1. 别名只影响由 [inlined](#server-deps-inline) 模块直接用 `import` 关键字导入的模块(默认情况下所有源代码都是内联的)。 2. Vitest 不支持对 `require` 调用进行别名。 3. 如果我们要别名外部依赖(例如,`react` -> `preact`),我们可能需要别名实际的 `node_modules` 包,以使其适用于外部依赖。[Yarn](https://classic.yarnpkg.com/en/docs/cli/add/#toc-yarn-add-alias) 和 [pnpm](https://pnpm.io/aliases/) 都支持通过 `npm:` 前缀进行别名。 - ::: +::: ### globals @@ -583,7 +583,7 @@ export default { Vitest 还通过 `vitest/environments` 入口导出 `builtinEnvironments`,以防你只想扩展它。 你可以在 [测试环境指南](/guide/environment) 中阅读有关扩展测试环境的更多信息。 ::: tip -jsdom 环境变量导出了等同于当前[JSDOM](https://github.com/jsdom/jsdom) 的 `jsdom` 全局变量实例。如果你想让 TypeScript 识别它,可以在使用此环境时将 `vitest/jsdom`添加到 `tsconfig.json` 中: +jsdom 环境变量导出了等同于当前 [JSDOM](https://github.com/jsdom/jsdom) 的 `jsdom` 全局变量实例。如果你想让 TypeScript 识别它,可以在使用此环境时将 `vitest/jsdom`添加到 `tsconfig.json` 中: ```json [tsconfig.json] { @@ -710,9 +710,9 @@ export default defineConfig({ #### vmThreads -在 `threads` 线程池中使用[ VM 上下文](https://nodejs.org/api/vm.html)(在受限环境中)运行测试。 +在 `threads` 线程池中使用 [VM 上下文](https://nodejs.org/api/vm.html)(在沙箱环境中)运行测试。 -这样可以加快测试速度,但是当运行[ ESM 代码](https://github.com/nodejs/node/issues/37648)时,VM 模块可能不稳定。你的测试可能会[泄漏内存](https://github.com/nodejs/node/issues/33439),为了解决这个问题,考虑手动编辑 [`poolOptions.vmThreads.memoryLimit`](#pooloptions-vmthreads-memorylimit) 的值。 +这样可以加快测试速度,但是当运行 [ESM 代码](https://github.com/nodejs/node/issues/37648) 时,VM 模块可能不稳定。你的测试可能会 [泄漏内存](https://github.com/nodejs/node/issues/33439),为了解决这个问题,考虑手动编辑 [`poolOptions.vmThreads.memoryLimit`](#pooloptions-vmthreads-memorylimit) 的值。 ::: warning 在沙箱中运行代码有一些优点(测试速度更快),但也有许多缺点。 @@ -764,7 +764,7 @@ export default defineConfig({ ##### poolOptions.threads.maxThreads - **类型:** `number | string` -- **默认值:** _available CPUs_ +- **默认值:** _可用 CPU 核心数_ 最大线程数或百分比。还可以使用`VITEST_MAX_THREADS`环境变量进行设置。 @@ -810,7 +810,7 @@ export default defineConfig({ #### poolOptions.forks -`forks` 池的选项。 +`forks` 池相关选项。 ```ts import { defineConfig } from 'vitest/config' @@ -829,7 +829,7 @@ export default defineConfig({ ##### poolOptions.forks.maxForks - **类型:** `number | string` -- **默认值:** _available CPUs_ +- **默认值:** _可用 CPU 核心数_ 最大分支数量或百分比。你也可以使用 `VITEST_MAX_FORKS` 环境变量。 @@ -885,7 +885,7 @@ export default defineConfig({ ##### poolOptions.vmThreads.maxThreads - **类型:** `number | string` -- **默认:** _available CPUs_ +- **默认值:** _可用 CPU 核心数_ 最大线程数或百分比。还可以使用`VITEST_MAX_THREADS`环境变量进行设置。 @@ -906,11 +906,12 @@ export default defineConfig({ - 有单位时 - `50%` - 如上,占系统总内存的百分比 - `100KB`, `65MB`, 等 - 用单位表示固定的内存限制 - - `K` / `KB` - Kilobytes (x1000) - - `KiB` - Kibibytes (x1024) - - `M` / `MB` - Megabytes - `MiB` - Mebibytes - - `G` / `GB` - Gigabytes - `GiB` - Gibibytes - + - `K` / `KB` - 千字节 (x1000) + - `KiB` - 千字节 (x1024) + - `M` / `MB`- 千字节 + - `MiB` - 兆字节 + - `G` / `GB` - 千兆字节 + - `GiB` - 千兆字节 ::: ::: warning @@ -939,7 +940,7 @@ export default defineConfig({ #### poolOptions.vmForks -`vmForks` 池的选项 +`vmForks` 池相关选项 ```ts import { defineConfig } from 'vitest/config' @@ -958,7 +959,7 @@ export default defineConfig({ ##### poolOptions.vmForks.maxForks - **类型:** `number | string` -- **默认值:** _available CPUs_ +- **默认值:** _可用 CPU 核心数_ 最大线程数或百分比。你也可以使用 `VITEST_MAX_FORKS` 环境变量。 @@ -989,7 +990,7 @@ export default defineConfig({ 所有测试文件应该并行运行。将其设置为 `false` 将覆盖 `maxWorkers` 和 `minWorkers` 选项为 `1`。 ::: tip -此选项不会影响在同一文件中运行的测试。如果你想并行运行这些程序,请在[description](/api/#describe-concurrent)或通过[a config](#sequence-concurrent) 上使用 `concurrent` 选项。 +此选项不会影响在同一文件中运行的测试。如果你想并行运行这些程序,请在 [description](/api/#describe-concurrent) 或通过 [配置](#sequence-concurrent) 上使用 `concurrent` 选项。 ::: ### maxWorkers {#maxworkers} @@ -1001,7 +1002,7 @@ export default defineConfig({ ### testTimeout - **类型:** `number` -- **默认值:** `5_000` in Node.js, `15_000` if `browser.enabled` is `true` +- **默认值:** 在 Node.js 环境下为 `5_000`,当 browser.enabled 为 `true` 时为 `15_000` - **命令行终端:** `--test-timeout=5000`, `--testTimeout=5000` 测试的默认超时时间(以毫秒为单位)。使用 `0` 完全禁用超时。 @@ -1009,7 +1010,7 @@ export default defineConfig({ ### hookTimeout - **类型:** `number` -- **默认值:** `10_000` in Node.js, `30_000` if `browser.enabled` is `true` +- **默认值:** 在 Node.js 环境下为 `10_000`,当 browser.enabled 为 `true` 时为 `30_000` - **命令行终端:** `--hook-timeout=10000`, `--hookTimeout=10000` 钩子(hook)的默认超时时间(以毫秒为单位)。使用 `0` 完全禁用超时。 @@ -1036,7 +1037,7 @@ Vitest 关闭时等待关闭的默认超时时间,以毫秒为单位 - **类型:** `string | string[]` -setup 文件的路径。它们将运行在每个测试文件之前。 +setup 文件的路径。它们将在每个测试文件之前运行。 ::: info 提示 编辑设置文件将自动触发所有测试的重新运行。 @@ -1095,7 +1096,7 @@ test('api key is defined', () => { ::: ::: warning -属性必须是字符串,值必须是[可序列化](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types),因为该对象将在不同进程之间传输。 +属性必须是字符串,值必须是 [可序列化](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types),因为该对象将在不同进程之间传输。 ::: ::: tip @@ -1246,7 +1247,7 @@ npx vitest --coverage.enabled --coverage.provider=istanbul - **可用的测试提供者:** `'v8' | 'istanbul'` - **命令行终端:** `--coverage.exclude=`, `--coverage.exclude= --coverage.exclude=` -想要查看示例,请参考 [如何在覆盖率报告中包含或排除文件](/guide/coverage.html#including-and-excluding-files-from-coverage-report)。 +可以参考 [如何在覆盖率报告中包含或排除文件](/guide/coverage.html#including-and-excluding-files-from-coverage-report) 里的示例。 #### coverage.clean @@ -1279,7 +1280,7 @@ npx vitest --coverage.enabled --coverage.provider=istanbul 配置测试覆盖率报告写入的目录。 -要预览覆盖范围报告,请使用 [HTML reporter](/guide/reporters.html#html-reporter), 该选项必须设置为 html 报告目录的子目录 (比如 `./html/coverage`). +要预览覆盖范围报告,请使用 [HTML 报告器](/guide/reporters.html#html-reporter), 该选项必须设置为 html 报告目录的子目录 (比如 `./html/coverage`). #### coverage.reporter @@ -1306,7 +1307,7 @@ npx vitest --coverage.enabled --coverage.provider=istanbul } ``` -我们还可以传递自定义覆盖报告器。查看[自定义覆盖报告器](/guide/coverage#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A6%86%E7%9B%96%E7%8E%87%E6%8F%90%E4%BE%9B%E8%80%85)了解更多详情。 +我们还可以传递自定义覆盖报告器。查看 [自定义覆盖率的报告器](/guide/coverage#custom-coverage-reporter) 了解更多详情。 @@ -1324,7 +1325,7 @@ npx vitest --coverage.enabled --coverage.provider=istanbul } ``` -我们可以在 Vitest UI 中查看覆盖率报告:查看 [Vitest UI Coverage](/guide/coverage#vitest-ui) 了解更多详情。 +我们可以在 Vitest UI 中查看覆盖率报告:查看 [UI 模式](/guide/coverage#vitest-ui) 了解更多详情。 #### coverage.reportOnFailure {#coverage-reportonfailure} @@ -1627,12 +1628,12 @@ test('doNotRun', () => { 提供 API 服务的端口。当设置为 true 时,默认端口为 51204 -### browser experimental {#browser} +### browser 实验性 {#browser} - **默认值:** `{ enabled: false }` - **命令行终端:** `--browser=`, `--browser.name=chrome --browser.headless` -运行浏览器测试的配置。请参阅[“浏览器配置参考”](/guide/browser/config)。 +运行浏览器测试的配置。请参阅 [“浏览器配置”](/guide/browser/config)。 ::: warning 这是一项实验性功能。重大更改可能不会遵循 semver,请在使用时锁定 Vitest 的版本。 @@ -1643,7 +1644,7 @@ test('doNotRun', () => { - **类型:** `boolean` - **默认值:** `false` -每个测试开始前自动调用 [`vi.clearAllMocks()`](/api/vi#vi-clearallmocks),仅清除 mock 调用记录,不影响其实现。 +每次测试前,都会对所有 momo 调用 [`.mockClear()`](/api/mock#mockclear)。这将清除模拟历史记录,而不会影响模拟实现。 ### mockReset @@ -1690,12 +1691,12 @@ test('doNotRun', () => { - **类型:** `string[]` - **默认值:** `[]` -快照测试的快照序列化程序模块的路径列表,如果要添加自定义快照序列化器,则非常有用。有关详细信息,请参阅[自定义序列化器](/guide/snapshot#custom-serializer)。 +快照测试的快照序列化程序模块的路径列表,如果要添加自定义快照序列化器,则非常有用。有关详细信息,请参阅 [自定义序列化器](/guide/snapshot#custom-serializer)。 ### resolveSnapshotPath - **类型**: `(testPath: string, snapExtension: string, context: { config: SerializedConfig }) => string` -- **默认值**: stores snapshot files in `__snapshots__` directory +- **默认值**: 将快照文件存储在 `__snapshots__` 目录中 覆盖快照的默认路径。例如,要在测试文件旁边存储一下快照: @@ -1859,7 +1860,7 @@ npx vitest --sequence.shuffle --sequence.seed=1000 此设置仅影响项目运行的顺序,而不影响项目中测试的顺序。 要控制项目内的测试隔离或测试顺序,请使用 [`isolate`](#isolate) 和 [`sequence.sequencer`](#sequence-sequencer) 选项。 -::: 详细信息示例 +::: details 示例 考虑这个例子: ```ts @@ -1916,29 +1917,25 @@ export default defineConfig({ 如果你希望测试随机运行,可以使用此选项或 CLI 参数 [`--sequence.shuffle`](/guide/cli) 启用它。 -Vitest 通常使用缓存对测试进行排序,因此长时间运行的测试会更早开始 - 这会使测试运行得更快。 如果你的测试将以随机顺序运行,你将失去这种性能改进,但跟踪意外依赖于先前运行的测试可能很有用。 - -- **类型**: `boolean | { files?, tests? }` -- **默认值**: `false` -- **命令行终端**: `--sequence.shuffle`, `--sequence.shuffle=false` +Vitest 通常使用缓存对测试进行排序,因此长时间运行的测试会更早开始,这会使测试运行得更快。如果你的测试将以随机顺序运行,你将失去这种性能改进,但跟踪意外依赖于先前运行的测试可能很有用。 -#### sequence.shuffle.files {#sequence-shuffle-files} +#### sequence.shuffle.files - **类型**: `boolean` - **默认值**: `false` - **命令行终端**: `--sequence.shuffle.files`, `--sequence.shuffle.files=false` -是否随机化文件,注意如果启用此选项,长时间运行的测试将不会提前启动。 +是否随机执行测试文件顺序。请注意,若启用此选项,耗时较长的测试将不会提前开始执行。 -#### sequence.shuffle.tests {#sequence-shuffle-tests} +#### sequence.shuffle.tests - **类型**: `boolean` - **默认值**: `false` - **命令行终端**: `--sequence.shuffle.tests`, `--sequence.shuffle.tests=false` -是否随机测试。 +是否随机执行测试顺序。 -#### sequence.concurrent {#sequence-concurrent} +#### sequence.concurrent - **类型**: `boolean` - **默认值**: `false` @@ -1983,7 +1980,7 @@ Vitest 通常使用缓存对测试进行排序,因此长时间运行的测试 ### typecheck -用于配置 [typechecking](/guide/testing-types) 测试环境的选项。 +[类型测试](/guide/testing-types) 测试环境的配置选项。 #### typecheck.enabled {#typecheck-enabled} @@ -1991,7 +1988,7 @@ Vitest 通常使用缓存对测试进行排序,因此长时间运行的测试 - **默认值**: `false` - **命令行终端**: `--typecheck`, `--typecheck.enabled` -常规测试时是否进行类型检查。 +在常规测试的同时启用类型检查。 #### typecheck.only {#typecheck-only} @@ -2065,7 +2062,7 @@ Vitest 通常使用缓存对测试进行排序,因此长时间运行的测试 - **默认值**: `300` - **命令行终端:**:`--slow-test-threshold=`, `--slowTestThreshold=` -如果测试被认为是缓慢的,那么会在报告结果中显示毫秒值。 +测试或测试套件执行超过该毫秒数即被视为缓慢,并在结果中相应标注。 ### chaiConfig {#chaiconfig} @@ -2356,7 +2353,7 @@ Expand all common lines. 在隔离的环境中运行测试。此选项对 `vmThreads` 和 `vmForks` 池没有影响。 -如果你的代码不依赖于副作用(对于具有 `node` 环境的项目通常如此),禁用此选项可能会[改进性能](/guide/improving-performance)。 +如果你的代码不依赖于副作用(这在 `node` 环境的项目通常如此),禁用此选项可能会 [性能提升](/guide/improving-performance)。 ::: tip 你可以使用 [`poolOptions`](#poolOptions) 属性禁用特定池的隔离。 diff --git a/guide/browser/assertion-api.md b/guide/browser/assertion-api.md index c2eb7ad0..d36b248c 100644 --- a/guide/browser/assertion-api.md +++ b/guide/browser/assertion-api.md @@ -284,13 +284,13 @@ function toBeVisible(): Promise 若要检查列表中至少有一个元素是可见的,请使用 `locator.first()`。 ```ts -// A specific element is visible. +// 检测指定元素可见 await expect.element(page.getByText('Welcome')).toBeVisible() -// At least one item in the list is visible. +// 检测列表中至少有一项可见 await expect.element(page.getByTestId('todo-item').first()).toBeVisible() -// At least one of the two elements is visible, possibly both. +// 检测两个元素中至少有一个可见(可能同时可见) await expect.element( page.getByRole('button', { name: 'Sign in' }) .or(page.getByRole('button', { name: 'Sign up' })) @@ -308,14 +308,16 @@ This allows you to check if an element is currently in viewport with [Intersecti You can pass `ratio` argument as option, which means the minimal ratio of the element should be in viewport. `ratio` should be in 0~1. +该方法通过 IntersectionObserver API检测元素是否位于当前视口内。 +可通过 ratio参数指定元素在视口中的最小可见比例(取值范围为 0~1): ```ts -// A specific element is in viewport. +// 检测指定元素是否在视口中 await expect.element(page.getByText('Welcome')).toBeInViewport() -// 50% of a specific element should be in viewport +// 检测指定元素在视窗范围内至少 50% 可见 await expect.element(page.getByText('To')).toBeInViewport({ ratio: 0.5 }) -// Full of a specific element should be in viewport +// 检测指定元素在视窗范围内完全可见 await expect.element(page.getByText('Vitest')).toBeInViewport({ ratio: 1 }) ``` @@ -379,9 +381,9 @@ await expect.element(getByTestId('parent')).toContainHTML('') function toHaveAccessibleDescription(description?: string | RegExp): Promise ``` -这允许你断言一个元素具有预期的[可访问描述](https://w3c.github.io/accname/)。 +这允许你断言一个元素具有预期的 [可访问描述](https://w3c.github.io/accname/)。 -你可以传递预期的可访问描述的确切字符串,或者通过传递正则表达式来进行部分匹配,或者使用[`expect.stringContaining`](/api/expect#expect-stringcontaining)或[`expect.stringMatching`](/api/expect#expect-stringmatching)。 +你可以传递预期的可访问描述的确切字符串,或者通过传递正则表达式来进行部分匹配,或者使用 [`expect.stringContaining`](/api/expect#expect-stringcontaining) 或 [`expect.stringMatching`](/api/expect#expect-stringmatching)。 ```html ``` -这允许你断言一个元素具有预期的[可访问错误消息](https://w3c.github.io/aria/#aria-errormessage)。 +这允许你断言一个元素具有预期的 [可访问错误消息](https://w3c.github.io/aria/#aria-errormessage)。 -你可以传递预期的可访问错误消息的确切字符串。或者,你可以通过传递正则表达式或使用[`expect.stringContaining`](/api/expect#expect-stringcontaining)或[`expect.stringMatching`](/api/expect#expect-stringmatching)来进行部分匹配。 +你可以传递预期的可访问错误消息的确切字符串。或者,你可以通过传递正则表达式或使用 [`expect.stringContaining`](/api/expect#expect-stringcontaining) 或 [`expect.stringMatching`](/api/expect#expect-stringmatching)来进行部分匹配。 ```html ``` ```ts -// Inputs with Valid Error Messages +// 有效错误信息的输入项 await expect.element(getByRole('textbox', { name: 'Has Error' })).toHaveAccessibleErrorMessage() await expect.element(getByRole('textbox', { name: 'Has Error' })).toHaveAccessibleErrorMessage( 'This field is invalid', @@ -462,7 +464,7 @@ await expect.element( getByRole('textbox', { name: 'Has Error' }), ).not.toHaveAccessibleErrorMessage('This field is absolutely correct!') -// Inputs without Valid Error Messages +// 没有效错误信息的输入项 await expect.element( getByRole('textbox', { name: 'No Error Attributes' }), ).not.toHaveAccessibleErrorMessage() @@ -480,7 +482,7 @@ function toHaveAccessibleName(name?: string | RegExp): Promise 这允许你断言一个元素具有预期的[可访问名称](https://w3c.github.io/accname/)。例如,它有助于断言表单元素和按钮是否被正确标记。 -你可以传递预期的可访问名称的确切字符串,或者通过传递正则表达式进行部分匹配,也可以使用[`expect.stringContaining`](/api/expect#expect-stringcontaining)或[`expect.stringMatching`](/api/expect#expect-stringmatching)。 +你可以传递预期的可访问名称的确切字符串,或者通过传递正则表达式进行部分匹配,也可以使用 [`expect.stringContaining`](/api/expect#expect-stringcontaining) 或 [`expect.stringMatching`](/api/expect#expect-stringmatching)。 ```html Test alt @@ -510,7 +512,7 @@ await expect.element(getByTestId('input-title')).toHaveAccessibleName() function toHaveAttribute(attribute: string, value?: unknown): Promise ``` -这允许你检查给定的元素是否具有某个属性。你还可以选择性地验证该属性是否具有特定的预期值或使用[`expect.stringContaining`](/api/expect#expect-stringcontaining)或[`expect.stringMatching`](/api/expect#expect-stringmatching)进行部分匹配。 +这允许你检查给定的元素是否具有某个属性。你还可以选择性地验证该属性是否具有特定的预期值或使用 [`expect.stringContaining`](/api/expect#expect-stringcontaining) 或 [`expect.stringMatching`](/api/expect#expect-stringmatching)进行部分匹配。 ```html @@ -542,7 +544,7 @@ function toHaveClass(...classNames: (string | RegExp)[]): Promise 这允许你检查给定元素在其 `class` 属性中是否包含某些类。除非你断言该元素没有任何类,否则必须提供至少一个类。 -类名列表可以包括字符串和正则表达式。正则表达式会与目标元素中的每个单独类进行匹配,**而不是与其完整的 `class` 属性值整体匹配**。 +类名列表可以包括字符串和正则表达式。正则表达式会与目标元素中的每个单独类进行匹配,而不是与其完整的 `class` 属性值整体匹配。 ::: warning 请注意,当仅提供正则表达式时,不能使用 `exact: true` 选项。 @@ -566,14 +568,14 @@ await expect.element(deleteButton).toHaveClass('btn-danger', 'btn') await expect.element(deleteButton).not.toHaveClass('btn-link') await expect.element(deleteButton).not.toHaveClass(/link/) -// ⚠️ regexp matches against individual classes, not the whole classList +// ⚠️ 正则表达式仅匹配单个类名而非整个 classList await expect.element(deleteButton).not.toHaveClass(/btn extra/) -// the element has EXACTLY a set of classes (in any order) +// 精确匹配类集合(顺序无关) await expect.element(deleteButton).toHaveClass('btn-danger extra btn', { exact: true }) -// if it has more than expected it is going to fail +// 若存在多余类则断言失败 await expect.element(deleteButton).not.toHaveClass('btn-danger extra', { exact: true }) @@ -705,7 +707,7 @@ function toHaveTextContent( 若要进行不区分大小写的匹配,可以使用带有 `/i` 修饰符的 `RegExp`。 -如果你想匹配整个内容,可以使用 `RegExp` 来实现。 +如果你想匹配整段内容,可以使用 `RegExp` 来实现。 ```html Text Content @@ -715,9 +717,9 @@ function toHaveTextContent( const element = getByTestId('text-content') await expect.element(element).toHaveTextContent('Content') -// to match the whole content +// 匹配整段内容 await expect.element(element).toHaveTextContent(/^Text Content$/) -// to use case-insensitive match +// 不区分大小写匹配 await expect.element(element).toHaveTextContent(/content$/i) await expect.element(element).not.toHaveTextContent('content') ``` @@ -903,11 +905,11 @@ await expect.element(inputCheckboxIndeterminate).toBePartiallyChecked() function toHaveRole(role: ARIARole): Promise ``` -这允许你断言某个元素具有预期的[角色](https://www.w3.org/TR/html-aria/#docconformance)。 +这允许你断言某个元素具有预期的 [角色](https://www.w3.org/TR/html-aria/#docconformance)。 在你已经通过某种查询(而非角色本身)获取到某个元素,并希望对其可访问性进行更多断言时,这非常有用。 -角色可以匹配显式角色(通过 `role` 属性),也可以通过[隐式 ARIA 语义](https://www.w3.org/TR/html-aria/#docconformance)匹配隐式角色。 +角色可以匹配显式角色(通过 `role` 属性),也可以通过 [隐式 ARIA 语义](https://www.w3.org/TR/html-aria/#docconformance) 匹配隐式角色。 ```html @@ -979,12 +981,12 @@ selection.removeAllRanges() selection.empty() selection.addRange(range) -// selection of child applies to the parent as well +// 子元素的选择同样适用于父元素 range.selectNodeContents(getByTestId('child').element()) await expect.element(getByTestId('child')).toHaveSelection('selected') await expect.element(getByTestId('parent')).toHaveSelection('selected') -// selection that applies from prev all, parent text before child, and part child. +// 选择范围包含:前序同级元素、父元素中子元素前的文本、以及子元素的部分内容 range.setStart(getByTestId('prev').element(), 0) range.setEnd(getByTestId('child').element().childNodes[0], 3) await expect.element(queryByTestId('prev')).toHaveSelection('prev') @@ -992,7 +994,7 @@ await expect.element(queryByTestId('child')).toHaveSelection('sel') await expect.element(queryByTestId('parent')).toHaveSelection('text sel') await expect.element(queryByTestId('next')).not.toHaveSelection() -// selection that applies from part child, parent text after child and part next. +// 选择范围包含:子元素的部分内容、父元素中子元素后的文本、以及后续同级元素的部分内容 range.setStart(getByTestId('child').element().childNodes[0], 3) range.setEnd(getByTestId('next').element().childNodes[0], 2) await expect.element(queryByTestId('child')).toHaveSelection('ected') diff --git a/guide/browser/commands.md b/guide/browser/commands.md index e0a248e3..d7d2595c 100644 --- a/guide/browser/commands.md +++ b/guide/browser/commands.md @@ -59,7 +59,7 @@ expect(input).toHaveValue('a') CDP session仅适用于 `playwright` provider,并且仅在使用 `chromium` 浏览器时有效。有关详细信息,请参阅 playwright 的 [`CDPSession`](https://playwright.dev/docs/api/class-cdpsession)文档。 ::: -## Custom Commands +## 自定义命令 {#custom-commands} 我们也可以通过 [`browser.commands`](/guide/browser/config#browser-commands) 配置选项添加自己的命令。如果我们正在开发一个库,可以通过插件内的`config`钩子来提供它们: @@ -108,7 +108,8 @@ test('custom command works correctly', async () => { expect(result).toEqual({ someValue: true }) }) -// if you are using TypeScript, you can augment the module +// 如果你正在使用 TypeScript,你可以扩展类型声明: + declare module 'vitest/browser' { interface BrowserCommands { myCustomCommand: (arg1: string, arg2: string) => Promise<{ @@ -122,7 +123,7 @@ declare module 'vitest/browser' { 如果自定义命令具有相同的名称,则它们将覆盖内置命令。 ::: -### 自定义命令 `playwright` {#custom-playwright-commands} +### 自定义 `playwright` 命令 {#custom-playwright-commands} Vitest 在命令上下文中公开了几个`playwright`特定属性。 @@ -148,7 +149,7 @@ export const myCommand: BrowserCommand<[string, number]> = async ( } ``` -### Custom `webdriverio` commands +### 自定义 `webdriverio` 命令 {#custom-webdriverio-commands} Vitest 在上下文对象上公开了一些 `webdriverio` 特有属性。 diff --git a/guide/browser/context.md b/guide/browser/context.md index 2e5f6c07..fa45acd3 100644 --- a/guide/browser/context.md +++ b/guide/browser/context.md @@ -9,7 +9,7 @@ Vitest 通过 `vitest/browser` 入口点公开上下文模块。从 2.0 开始 ## `userEvent` ::: tip -`userEvent` API 的详细说明见[Interactivity API](/guide/browser/interactivity-api). +`userEvent` API 的详细说明见[Interactivity API](/guide/browser/interactivity-api)。 ::: ```ts @@ -43,7 +43,7 @@ export const userEvent: { ## `commands` ::: tip -Commands API 的详细说明见[Commands API](/guide/browser/commands). +Commands API 的详细说明见 [Commands API](/guide/browser/commands)。 ::: ```ts @@ -141,10 +141,6 @@ await frame.click() // ❌ Not available ## `cdp` -```ts -function cdp(): CDPSession -``` - `cdp` 导出返回当前的 Chrome DevTools 协议会话。它主要用于库作者在其基础上构建工具。 ::: warning diff --git a/guide/browser/index.md b/guide/browser/index.md index 109639a7..6ab7b1e3 100644 --- a/guide/browser/index.md +++ b/guide/browser/index.md @@ -8,7 +8,7 @@ outline: deep 此页面提供有关 Vitest API 中实验性浏览器模式功能的信息,该功能允许你在浏览器中本地运行测试,提供对窗口和文档等浏览器全局变量的访问。此功能目前正在开发中,API 未来可能会更改。 ::: tip -如果你需要 `expect` 、`vi` ,或者像测试项目、类型测试等通用 API 的文档,请查看 [「快速上手」指南](/guide/)。 +如果你需要 `expect` 、`vi` ,或者像测试项目、类型测试等通用 API 的文档,请查看 [“快速起步” 指南](/guide/)。 ::: Vitest UI @@ -35,7 +35,7 @@ bunx vitest init browser ### 手动安装 {#manual-installation} -我们也可以手动安装软件包。默认情况下,浏览器模式不需要任何额外的 E2E provider 就能在本地运行测试,因为它会复用你现有的浏览器。 +我们也可以手动安装软件包。默认情况下,浏览器模式不需要任何额外的端到端 provider 就能在本地运行测试,因为它会复用你现有的浏览器。 ::: code-group ```bash [npm] @@ -106,7 +106,7 @@ export default defineConfig({ browser: { provider: playwright(), enabled: true, - // at least one instance is required + // 至少需要一个实例 instances: [ { browser: 'chromium' }, ], @@ -245,8 +245,8 @@ export default defineConfig({ projects: [ { test: { - // an example of file based convention, - // you don't have to follow it + // 基于文件命名约定的示例 + // 非强制要求 include: [ 'tests/unit/**/*.{test,spec}.ts', 'tests/**/*.unit.{test,spec}.ts', @@ -257,8 +257,8 @@ export default defineConfig({ }, { test: { - // an example of file based convention, - // you don't have to follow it + // 基于文件命名约定的示例 + // 非强制要求 include: [ 'tests/browser/**/*.{test,spec}.ts', 'tests/**/*.browser.{test,spec}.ts', @@ -278,9 +278,9 @@ export default defineConfig({ }) ``` -## Browser Option Types +## 浏览器选项类型 {#browser-option-types} -Vitest 中的浏览器选项取决于provider。如果在配置文件中传递 `--browser` 且未指定其名称,则 Vitest 将失败。可用选项: +Vitest 中的浏览器选项取决于 provider。如果在配置文件中传递 `--browser` 且未指定其名称,则 Vitest 将失败。可用选项: - `webdriverio` 支持这些浏览器: - `firefox` - `chrome` @@ -291,18 +291,18 @@ Vitest 中的浏览器选项取决于provider。如果在配置文件中传递 ` - `webkit` - `chromium` -## Browser Compatibility +## 浏览器兼容性 {#browser-compatibility} Vitest 使用 [Vite dev server](https://cn.vitejs.dev/guide/#browser-support) 来运行我们的测试,因此我们只支持 [`esbuild.target`](https://cn.vitejs.dev/config/shared-options#esbuild)选项(默认为 `esnext`)中指定的功能。 -默认情况下,Vite 的目标浏览器支持本地 [ES Modules](https://caniuse.com/es6-module)、本地 [ESM dynamic import](https://caniuse.com/es6-module-dynamic-import) 和 [`import.meta`](https://caniuse.com/mdn-javascript_operators_import_meta)。此外,我们还利用 [`BroadcastChannel`](https://caniuse.com/?search=BroadcastChannel)在 iframe 之间进行通信: +默认情况下,Vite 的目标浏览器支持原生 [ES Modules](https://caniuse.com/es6-module)、原生 [ESM 动态导入](https://caniuse.com/es6-module-dynamic-import) 和 [`import.meta`](https://caniuse.com/mdn-javascript_operators_import_meta)。此外,我们还利用 [`BroadcastChannel`](https://caniuse.com/?search=BroadcastChannel)在 iframe 之间进行通信: - Chrome >=87 - Firefox >=78 - Safari >=15.4 - Edge >=88 -## Running Tests +## 运行测试 {#running-tests} 要使用 CLI 指定浏览器,请使用 `--browser` 标志后跟浏览器名称,如下所示: @@ -322,13 +322,13 @@ npx vitest --browser.headless Vitest 默认会在开发模式下自动打开浏览器界面,测试会在页面中央的 iframe 中执行。你可以通过选择界面中的预设尺寸、在测试中调用 `page.viewport` 方法,或者在 [配置文件](/config/#browser-viewport) 中设置默认值来调整视口大小。 -## Headless +## 无头模式 {#headless} -headless 模式是浏览器模式下可用的另一个选项。在 headless 模式下,浏览器在没有用户界面的情况下在后台运行,这对于运行自动化测试非常有用。Vitest 中的 headless 选项可以设置为布尔值以启用或禁用 headless 模式。 +无头模式是浏览器模式下可用的另一个选项。在无头模式下,浏览器在没有用户界面的情况下在后台运行,这对于运行自动化测试非常有用。Vitest 中的 headless 选项可以设置为布尔值以启用或禁用无头模式。 -在使用 headless 模式时,Vitest 不会自动打开用户界面。如果我们希望继续使用用户界面,同时让测试以 headless 模式运行,我们可以安装`[@vitest/ui](/guide/ui)`包,并在运行Vitest时传递`--ui`标志。 +在使用无头模式时,Vitest 不会自动打开用户界面。如果我们希望继续使用用户界面,同时让测试以 无头模式运行,我们可以安装 [`@vitest/ui`](/guide/ui) 包,并在运行Vitest时传递 `--ui` 标志。 -这是启用 headless 模式的示例配置: +这是启用无头模式的示例配置: ```ts [vitest.config.ts] import { defineConfig } from 'vitest/config' @@ -345,19 +345,19 @@ export default defineConfig({ }) ``` -你还可以在 CLI 中使用 `--browser.headless` 标志设置 headless 模式,如下所示: +你还可以在 CLI 中使用 `--browser.headless` 标志设置无头模式,如下所示: ```sh npx vitest --browser.headless ``` -在这种情况下,Vitest 将使用 Chrome 浏览器以 headless 模式运行。 +在这种情况下,Vitest 将使用 Chrome 浏览器以无头模式运行。 ::: warning 默认情况下Headless模式不可用。我们需要使用 [`playwright`](https://npmjs.com/package/playwright) 或 [`webdriverio`](https://www.npmjs.com/package/webdriverio) 提供程序来启用此功能。 ::: -## Examples +## 示例 {#examples} 一般情况下,我们不需要任何依赖来使用浏览器模式: @@ -367,7 +367,7 @@ import { page } from 'vitest/browser' import { render } from './my-render-function.js' test('properly handles form inputs', async () => { - render() // mount DOM elements + render() // 挂载 DOM 元素 // 断言初始状态。 await expect.element(page.getByText('Hi, my name is Alice')).toBeInTheDocument() @@ -391,9 +391,9 @@ test('properly handles form inputs', async () => { 其他框架也有社区提供的软件包: -- [`vitest-browser-lit`](https://github.com/EskiMojo14/vitest-browser-lit) to render [lit](https://lit.dev) components -- [`vitest-browser-preact`](https://github.com/JoviDeCroock/vitest-browser-preact) to render [preact](https://preactjs.com) components -- [`vitest-browser-qwik`](https://github.com/kunai-consulting/vitest-browser-qwik) to render [qwik](https://qwik.dev) components +- [`vitest-browser-lit`](https://github.com/EskiMojo14/vitest-browser-lit) 渲染 [lit](https://lit.dev) 组件 +- [`vitest-browser-preact`](https://github.com/JoviDeCroock/vitest-browser-preact) 渲染 [preact](https://preactjs.com) 组件 +- [`vitest-browser-qwik`](https://github.com/kunai-consulting/vitest-browser-qwik) 渲染 [qwik](https://qwik.dev) 组件 如果你的框架没有被包含在内,请随时创建你自己的软件包——它是一个简单的封装,围绕着框架渲染器和 `page.elementLocator` API。我们会在本页面添加指向它的链接。请确保其名称以 `vitest-browser-` 开头。 @@ -406,7 +406,7 @@ import { page } from 'vitest/browser' await expect.element(page.getByText('Hello World')).toBeInTheDocument() ``` -Vitest 暴露了一个[上下文 API](/guide/browser/context),其中包含一组在测试中可能对你有用的实用程序。例如,如果你需要进行交互操作,比如点击元素或在输入框中输入文本,你可以使用来自 `vitest/browser` 的 `userEvent`。更多内容请参阅[交互性 API](/guide/browser/interactivity-api)。 +Vitest 暴露了一个 [上下文 API](/guide/browser/context),其中包含一组在测试中可能对你有用的实用程序。例如,如果你需要进行交互操作,比如点击元素或在输入框中输入文本,你可以使用来自 `vitest/browser` 的 `userEvent`。更多内容请参阅 [交互性 API](/guide/browser/interactivity-api)。 ```ts import { page, userEvent } from 'vitest/browser' @@ -520,8 +520,8 @@ Vitest 并不支持所有开箱即用的框架,但我们可以使用外部工 对于不支持的框架,我们建议使用 `testing-library` 软件包: -- [`@solidjs/testing-library`](https://testing-library.com/docs/solid-testing-library/intro) to render [solid](https://www.solidjs.com) components -- [`@marko/testing-library`](https://testing-library.com/docs/marko-testing-library/intro) to render [marko](https://markojs.com) components +- [`@solidjs/testing-library`](https://testing-library.com/docs/solid-testing-library/intro) 渲染 [solid](https://www.solidjs.com) 组件 +- [`@marko/testing-library`](https://testing-library.com/docs/marko-testing-library/intro) 渲染 [marko](https://markojs.com) 组件 我们还可以在 [`browser-examples`](https://github.com/vitest-tests/browser-examples) 中查看更多的案例。 @@ -583,7 +583,7 @@ test('renders a message', async () => { 在这类情况下,Vitest 会为相关 API 提供带有默认返回值的内置 mock,从而避免用户不小心使用同步弹窗等 Web API 时导致程序卡死。不过,仍然强烈建议用户自行对这些 Web API 进行 mock,以获得更稳定、可控的测试体验。更多内容可参考 [模拟](/guide/mocking) 章节。 -### 对模块的导出内容进行监听(Spy)。 {#spying-on-module-exports} +### 对模块的导出内容进行监听(Spy) {#spying-on-module-exports} 在浏览器模式下,Vitest 依赖浏览器自身对 ESM 模块的原生支持来加载模块。此时,模块的命名空间对象是不可修改的,这与 Node.js 测试中 Vitest 能够对模块执行打补丁不同。因此,你不能对通过 import 导入的对象使用 `vi.spyOn` : diff --git a/guide/browser/interactivity-api.md b/guide/browser/interactivity-api.md index ea88e14e..ebd7f765 100644 --- a/guide/browser/interactivity-api.md +++ b/guide/browser/interactivity-api.md @@ -148,7 +148,7 @@ function fill( ): Promise ``` -为 `input` `、textarea` 或 `contenteditable` 元素设置新的内容,并且在赋值前会先清空其中已有的文本。 +为 `input` 、 `textarea` 或 `contenteditable` 元素设置新的内容,并且在赋值前会先清空其中已有的文本。 ```ts import { page, userEvent } from 'vitest/browser' diff --git a/guide/browser/multiple-setups.md b/guide/browser/multiple-setups.md index 95d070a2..e20d8d5f 100644 --- a/guide/browser/multiple-setups.md +++ b/guide/browser/multiple-setups.md @@ -1,4 +1,4 @@ -# 多种设置 {#multiple-setups} +# 多环境配置 {#multiple-setups} 你可以使用 [`browser.instances`](/guide/browser/config#browser-instances) 选项来指定多个不同的浏览器设置。 @@ -28,7 +28,7 @@ export default defineConfig({ }) ``` -## 不同的设置 {#different-setups} +## 不同的配置方案 {#different-setups} 你还可以独立于浏览器指定不同的配置选项(尽管,实例也可以有 `browser` 字段): diff --git a/guide/cli-generated.md b/guide/cli-generated.md index 9ca5fc3c..6ff10e55 100644 --- a/guide/cli-generated.md +++ b/guide/cli-generated.md @@ -1,904 +1,904 @@ ### root -- **CLI:** `-r, --root ` -- **Config:** [root](/config/#root) +- **命令行终端:** `-r, --root ` +- **配置:** [root](/config/#root) 根路径 ### config -- **CLI:** `-c, --config ` +- **命令行终端:** `-c, --config ` 配置文件的路径 ### update -- **CLI:** `-u, --update` -- **Config:** [update](/config/#update) +- **命令行终端:** `-u, --update` +- **配置:** [update](/config/#update) 更新快照 ### watch -- **CLI:** `-w, --watch` -- **Config:** [watch](/config/#watch) +- **命令行终端:** `-w, --watch` +- **配置:** [watch](/config/#watch) 启用观察模式 ### testNamePattern -- **CLI:** `-t, --testNamePattern ` -- **Config:** [testNamePattern](/config/#testnamepattern) +- **命令行终端:** `-t, --testNamePattern ` +- **配置:** [testNamePattern](/config/#testnamepattern) 使用符合指定 regexp 模式的运行测试 ### dir -- **CLI:** `--dir ` -- **Config:** [dir](/config/#dir) +- **命令行终端:** `--dir ` +- **配置:** [dir](/config/#dir) 扫描测试文件的基本目录 ### ui -- **CLI:** `--ui` -- **Config:** [ui](/config/#ui) +- **命令行终端:** `--ui` +- **配置:** [ui](/config/#ui) -启用UI +启用 UI 模式 ### open -- **CLI:** `--open` -- **Config:** [open](/config/#open) +- **命令行终端:** `--open` +- **配置:** [open](/config/#open) 自动打开用户界面(默认值:`!process.env.CI`)。 ### api.port -- **CLI:** `--api.port [port]` +- **命令行终端:** `--api.port [port]` 指定服务器端口。注意,如果端口已被使用,Vite 会自动尝试下一个可用端口,因此这可能不是服务器最终监听的实际端口。如果为 `true`,将设置为`51204` ### api.host -- **CLI:** `--api.host [host]` +- **命令行终端:** `--api.host [host]` 指定服务器应该监听哪些 IP 地址。设为 `0.0.0.0` 或 `true` 则监听所有地址,包括局域网地址和公共地址 ### api.strictPort -- **CLI:** `--api.strictPort` +- **命令行终端:** `--api.strictPort` 设置为 true 时,如果端口已被使用,则退出,而不是自动尝试下一个可用端口 ### silent -- **CLI:** `--silent [value]` -- **Config:** [silent](/config/#silent) +- **命令行终端:** `--silent [value]` +- **配置:** [silent](/config/#silent) 测试的静默控制台输出。使用 `'passed-only'` 仅查看失败测试的日志。 ### hideSkippedTests -- **CLI:** `--hideSkippedTests` +- **命令行终端:** `--hideSkippedTests` 隐藏跳过测试的日志 ### reporters -- **CLI:** `--reporter ` -- **Config:** [reporters](/config/#reporters) +- **命令行终端:** `--reporter ` +- **配置:** [reporters](/config/#reporters) 指定报告器(default、blob、verbose、dot、json、tap、tap-flat、junit、tree、hanging-process、github-actions) ### outputFile -- **CLI:** `--outputFile ` -- **Config:** [outputFile](/config/#outputfile) +- **命令行终端:** `--outputFile ` +- **配置:** [outputFile](/config/#outputfile) -如果还指定了支持报告程序,则将测试结果写入文件,使用 cac 的点符号表示多个报告程序的单个输出结果 (比如: --outputFile.tap=./tap.txt) +如果还指定了支持报告程序,则将测试结果写入文件,使用 cac 的点符号表示多个报告程序的单个输出结果 (比如: `--outputFile.tap=./tap.txt`) ### coverage.provider -- **CLI:** `--coverage.provider ` -- **Config:** [coverage.provider](/config/#coverage-provider) +- **命令行终端:** `--coverage.provider ` +- **配置:** [coverage.provider](/config/#coverage-provider) 选择覆盖范围采集工具, 可用值为: "v8", "istanbul" and "custom" ### coverage.enabled -- **CLI:** `--coverage.enabled` -- **Config:** [coverage.enabled](/config/#coverage-enabled) +- **命令行终端:** `--coverage.enabled` +- **配置:** [coverage.enabled](/config/#coverage-enabled) 启用覆盖范围收集。可使用 `--coverage` CLI 选项覆盖(默认值:`false`)。 ### coverage.include -- **CLI:** `--coverage.include ` -- **Config:** [coverage.include](/config/#coverage-include) +- **命令行终端:** `--coverage.include ` +- **配置:** [coverage.include](/config/#coverage-include) 作为通配符模式包含在覆盖率中的文件。在使用多个模式时可以指定多次。默认情况下,只包含被测试覆盖的文件。 ### coverage.exclude -- **CLI:** `--coverage.exclude ` -- **Config:** [coverage.exclude](/config/#coverage-exclude) +- **命令行终端:** `--coverage.exclude ` +- **配置:** [coverage.exclude](/config/#coverage-exclude) 覆盖范围中要排除的文件。使用多个扩展名时,可指定多次。 ### coverage.clean -- **CLI:** `--coverage.clean` -- **Config:** [coverage.clean](/config/#coverage-clean) +- **命令行终端:** `--coverage.clean` +- **配置:** [coverage.clean](/config/#coverage-clean) 运行测试前清除覆盖结果(默认值:true) ### coverage.cleanOnRerun -- **CLI:** `--coverage.cleanOnRerun` -- **Config:** [coverage.cleanOnRerun](/config/#coverage-cleanonrerun) +- **命令行终端:** `--coverage.cleanOnRerun` +- **配置:** [coverage.cleanOnRerun](/config/#coverage-cleanonrerun) 重新运行监视时清理覆盖率报告(默认值:true) ### coverage.reportsDirectory -- **CLI:** `--coverage.reportsDirectory ` -- **Config:** [coverage.reportsDirectory](/config/#coverage-reportsdirectory) +- **命令行终端:** `--coverage.reportsDirectory ` +- **配置:** [coverage.reportsDirectory](/config/#coverage-reportsdirectory) 将覆盖率报告写入的目录(默认值: ./coverage) ### coverage.reporter -- **CLI:** `--coverage.reporter ` -- **Config:** [coverage.reporter](/config/#coverage-reporter) +- **命令行终端:** `--coverage.reporter ` +- **配置:** [coverage.reporter](/config/#coverage-reporter) 使用的报告。更多信息请访问 [`coverage.reporter`](https://vitest.dev/config/#coverage-reporter)。 (默认值: `["text", "html", "clover", "json"]`) ### coverage.reportOnFailure -- **CLI:** `--coverage.reportOnFailure` -- **Config:** [coverage.reportOnFailure](/config/#coverage-reportonfailure) +- **命令行终端:** `--coverage.reportOnFailure` +- **配置:** [coverage.reportOnFailure](/config/#coverage-reportonfailure) 即使测试失败也能生成覆盖率报告 (默认值: `false`) ### coverage.allowExternal -- **CLI:** `--coverage.allowExternal` -- **Config:** [coverage.allowExternal](/config/#coverage-allowexternal) +- **命令行终端:** `--coverage.allowExternal` +- **配置:** [coverage.allowExternal](/config/#coverage-allowexternal) 收集项目根目录外文件的覆盖范围(默认值:`false`) ### coverage.skipFull -- **CLI:** `--coverage.skipFull` -- **Config:** [coverage.skipFull](/config/#coverage-skipfull) +- **命令行终端:** `--coverage.skipFull` +- **配置:** [coverage.skipFull](/config/#coverage-skipfull) 不显示语句、分支和函数覆盖率为 100% 的文件(默认值:`false`) ### coverage.thresholds.100 -- **CLI:** `--coverage.thresholds.100` -- **Config:** [coverage.thresholds.100](/config/#coverage-thresholds-100) +- **命令行终端:** `--coverage.thresholds.100` +- **配置:** [coverage.thresholds.100](/config/#coverage-thresholds-100) 将所有覆盖率阈值设置为 100 的快捷方式(默认值:`false`) ### coverage.thresholds.perFile -- **CLI:** `--coverage.thresholds.perFile` -- **Config:** [coverage.thresholds.perFile](/config/#coverage-thresholds-perfile) +- **命令行终端:** `--coverage.thresholds.perFile` +- **配置:** [coverage.thresholds.perFile](/config/#coverage-thresholds-perfile) -查每个文件的阈值。 `--coverage.thresholds.lines`, `--coverage.thresholds.functions`, `--coverage.thresholds.branches`, `--coverage.thresholds.statements` 为实际阈值(默认值:`false`) +检查每个文件的阈值。 `--coverage.thresholds.lines`, `--coverage.thresholds.functions`, `--coverage.thresholds.branches`, `--coverage.thresholds.statements` 为实际阈值(默认值:`false`) ### coverage.thresholds.autoUpdate -- **CLI:** `--coverage.thresholds.autoUpdate ` -- **Config:** [coverage.thresholds.autoUpdate](/config/#coverage-thresholds-autoupdate) +- **命令行终端:** `--coverage.thresholds.autoUpdate ` +- **配置:** [coverage.thresholds.autoUpdate](/config/#coverage-thresholds-autoupdate) -更新阈值: 当当前覆盖率高于配置的阈值时,将 "lines"、"functions"、"branches"和 "statements"更新到配置文件(默认值:`false`) +更新阈值: 当前覆盖率高于配置的阈值时,将 "lines"、"functions"、"branches"和 "statements"更新到配置文件(默认值:`false`) ### coverage.thresholds.lines -- **CLI:** `--coverage.thresholds.lines ` +- **命令行终端:** `--coverage.thresholds.lines ` 针对代码行的覆盖度阈值设定,请访问 [istanbuljs](https://github.com/istanbuljs/nyc#coverage-thresholds) 了解更多信息。此选项不适用于自定义 providers ### coverage.thresholds.functions -- **CLI:** `--coverage.thresholds.functions ` +- **命令行终端:** `--coverage.thresholds.functions ` 针对函数的覆盖度阈值设定,请访问 [istanbuljs](https://github.com/istanbuljs/nyc#coverage-thresholds) 了解更多信息。 此选项不适用于自定义 providers ### coverage.thresholds.branches -- **CLI:** `--coverage.thresholds.branches ` +- **命令行终端:** `--coverage.thresholds.branches ` 针对 branches 的覆盖度阈值设定,请访问 [istanbuljs](https://github.com/istanbuljs/nyc#coverage-thresholds) 了解更多信息。 此选项不适用于自定义 providers ### coverage.thresholds.statements -- **CLI:** `--coverage.thresholds.statements ` +- **命令行终端:** `--coverage.thresholds.statements ` 针对 statements 的覆盖度阈值设定,请访问 [istanbuljs](https://github.com/istanbuljs/nyc#coverage-thresholds) 了解更多信息。 此选项不适用于自定义 providers ### coverage.ignoreClassMethods -- **CLI:** `--coverage.ignoreClassMethods ` -- **Config:** [coverage.ignoreClassMethods](/config/#coverage-ignoreclassmethods) +- **命令行终端:** `--coverage.ignoreClassMethods ` +- **配置:** [coverage.ignoreClassMethods](/config/#coverage-ignoreclassmethods) 覆盖时要忽略的类方法名称数组。更多信息请访问 [istanbuljs](https://github.com/istanbuljs/nyc#ignoring-methods) 。该选项仅适用于 istanbul providers(默认值:`[]`)。 ### coverage.processingConcurrency -- **CLI:** `--coverage.processingConcurrency ` -- **Config:** [coverage.processingConcurrency](/config/#coverage-processingconcurrency) +- **命令行终端:** `--coverage.processingConcurrency ` +- **配置:** [coverage.processingConcurrency](/config/#coverage-processingconcurrency) 处理覆盖率结果时使用的并发限制。 (默认最小值介于 20 和 CPU 数量之间) ### coverage.customProviderModule -- **CLI:** `--coverage.customProviderModule ` -- **Config:** [coverage.customProviderModule](/config/#coverage-customprovidermodule) +- **命令行终端:** `--coverage.customProviderModule ` +- **配置:** [coverage.customProviderModule](/config/#coverage-customprovidermodule) -指定自定义覆盖范围提供程序模块的模块名称或路径。 请访问[自定义 providers 覆盖范围](https://vitest.dev/guide/coverage#custom-coverage-provider) 了解更多信息。 此选项仅适用于自定义 providers +指定自定义覆盖范围提供程序模块的模块名称或路径。 请访问 [自定义 providers 覆盖范围](/guide/coverage#custom-coverage-provider) 了解更多信息。 此选项仅适用于自定义 providers ### coverage.watermarks.statements -- **CLI:** `--coverage.watermarks.statements ` +- **命令行终端:** `--coverage.watermarks.statements ` High and low watermarks for statements in the format of `,` ### coverage.watermarks.lines -- **CLI:** `--coverage.watermarks.lines ` +- **命令行终端:** `--coverage.watermarks.lines ` High and low watermarks for lines in the format of `,` ### coverage.watermarks.branches -- **CLI:** `--coverage.watermarks.branches ` +- **命令行终端:** `--coverage.watermarks.branches ` High and low watermarks for branches in the format of `,` ### coverage.watermarks.functions -- **CLI:** `--coverage.watermarks.functions ` +- **命令行终端:** `--coverage.watermarks.functions ` High and low watermarks for functions in the format of `,` ### mode -- **CLI:** `--mode ` -- **Config:** [mode](/config/#mode) +- **命令行终端:** `--mode ` +- **配置:** [mode](/config/#mode) 覆盖 Vite 模式 (默认值: `test` 或 `benchmark`) ### isolate -- **CLI:** `--isolate` -- **Config:** [isolate](/config/#isolate) +- **命令行终端:** `--isolate` +- **配置:** [isolate](/config/#isolate) 隔离运行每个测试文件。要禁用隔离, 使用 `--no-isolate` (默认值: `true`) ### globals -- **CLI:** `--globals` -- **Config:** [globals](/config/#globals) +- **命令行终端:** `--globals` +- **配置:** [globals](/config/#globals) 全局注入 ### dom -- **CLI:** `--dom` +- **命令行终端:** `--dom` 使用 happy-dom 模拟浏览器 API ### browser.enabled -- **CLI:** `--browser.enabled` -- **Config:** [browser.enabled](/guide/browser/config#browser-enabled) +- **命令行终端:** `--browser.enabled` +- **配置:** [browser.enabled](/guide/browser/config#browser-enabled) 在浏览器中运行测试。 相当于 `--browser.enabled` (默认值: `false`) ### browser.name -- **CLI:** `--browser.name ` -- **Config:** [browser.name](/guide/browser/config#browser-name) +- **命令行终端:** `--browser.name ` +- **配置:** [browser.name](/guide/browser/config#browser-name) 在特定浏览器中运行所有测试。某些浏览器仅适用于特定提供商(请参阅 `--browser.provider` )。访问 [`browser.name`](https://vitest.dev/guide/browser/config/#browser-name) 了解更多信息 ### browser.headless -- **CLI:** `--browser.headless` -- **Config:** [browser.headless](/guide/browser/config#browser-headless) +- **命令行终端:** `--browser.headless` +- **配置:** [browser.headless](/guide/browser/config#browser-headless) 在无头模式下运行浏览器(即不打开图形用户界面)。如果在 CI 中运行 Vitest,默认情况下将启用无头模式 (默认值: `process.env.CI`) ### browser.api.port -- **CLI:** `--browser.api.port [port]` -- **Config:** [browser.api.port](/guide/browser/config#browser-api-port) +- **命令行终端:** `--browser.api.port [port]` +- **配置:** [browser.api.port](/guide/browser/config#browser-api-port) 指定服务器端口。注意,如果端口已被使用,Vite 会自动尝试下一个可用端口,因此这可能不是服务器最终监听的实际端口。如果为 `true`,将设置为 `63315` ### browser.api.host -- **CLI:** `--browser.api.host [host]` -- **Config:** [browser.api.host](/guide/browser/config#browser-api-host) +- **命令行终端:** `--browser.api.host [host]` +- **配置:** [browser.api.host](/guide/browser/config#browser-api-host) 指定服务器应该监听哪些 IP 地址。设为 `0.0.0.0` 或 `true` 则监听所有地址,包括局域网地址和公共地址 ### browser.api.strictPort -- **CLI:** `--browser.api.strictPort` -- **Config:** [browser.api.strictPort](/guide/browser/config#browser-api-strictport) +- **命令行终端:** `--browser.api.strictPort` +- **配置:** [browser.api.strictPort](/guide/browser/config#browser-api-strictport) 设置为 true 时,如果端口已被使用,则退出,而不是自动尝试下一个可用端口 ### browser.provider -- **CLI:** `--browser.provider ` -- **Config:** [browser.provider](/guide/browser/config#browser-provider) +- **命令行终端:** `--browser.provider ` +- **配置:** [browser.provider](/guide/browser/config#browser-provider) 指定执行浏览器测试时所使用的提供程序。部分浏览器仅在特定的提供程序下可用。可选值有 "webdriverio"、"playwright"、"preview",也可以填写自定义提供程序的路径。更多信息请查看 [`browser.provider`](https://vitest.dev/guide/browser/config.html#browser-provider)(默认值为 "preview")。 ### browser.isolate -- **CLI:** `--browser.isolate` -- **Config:** [browser.isolate](/guide/browser/config#browser-isolate) +- **命令行终端:** `--browser.isolate` +- **配置:** [browser.isolate](/guide/browser/config#browser-isolate) 隔离运行每个浏览器测试文件。要禁用隔离请使用 `--browser.isolate=false` (默认值: `true`) ### browser.ui -- **CLI:** `--browser.ui` -- **Config:** [browser.ui](/guide/browser/config#browser-ui) +- **命令行终端:** `--browser.ui` +- **配置:** [browser.ui](/guide/browser/config#browser-ui) -运行测试时显示 Vitest UI(默认值: `!process.env.CI`) +运行测试时显示 Vitest UI (默认值: `!process.env.CI`) ### browser.fileParallelism -- **CLI:** `--browser.fileParallelism` -- **Config:** [browser.fileParallelism](/guide/browser/config#browser-fileparallelism) +- **命令行终端:** `--browser.fileParallelism` +- **配置:** [browser.fileParallelism](/guide/browser/config#browser-fileparallelism) -浏览器测试文件是否应并行运行。使用 `--browser.fileParallelism=false` 可禁用 (默认值: `true`) +浏览器测试文件是否应并行运行。使用 `--browser.fileParallelism=false` 进行禁用 (默认值: `true`) ### browser.connectTimeout -- **CLI:** `--browser.connectTimeout ` -- **Config:** [browser.connectTimeout](/guide/browser/config#browser-connecttimeout) +- **命令行终端:** `--browser.connectTimeout ` +- **配置:** [browser.connectTimeout](/guide/browser/config#browser-connecttimeout) -If connection to the browser takes longer, the test suite will fail (default: `60_000`) +如果连接浏览器时间超时,测试套件将失败 (默认值: `60_000`) ### browser.trackUnhandledErrors -- **CLI:** `--browser.trackUnhandledErrors` -- **Config:** [browser.trackUnhandledErrors](/guide/browser/config#browser-trackunhandlederrors) +- **命令行终端:** `--browser.trackUnhandledErrors` +- **配置:** [browser.trackUnhandledErrors](/guide/browser/config#browser-trackunhandlederrors) 控制 Vitest 是否捕获未捕获的异常以便报告(默认:`true`)。 ### browser.trace -- **CLI:** `--browser.trace ` -- **Config:** [browser.trace](/guide/browser/config#browser-trace) +- **命令行终端:** `--browser.trace ` +- **配置:** [browser.trace](/guide/browser/config#browser-trace) Enable trace view mode. Supported: "on", "off", "on-first-retry", "on-all-retries", "retain-on-failure". ### pool -- **CLI:** `--pool ` -- **Config:** [pool](/config/#pool) +- **命令行终端:** `--pool ` +- **配置:** [pool](/config/#pool) 如果未在浏览器中运行,则指定 pool (默认值: `threads`) ### poolOptions.threads.isolate -- **CLI:** `--poolOptions.threads.isolate` -- **Config:** [poolOptions.threads.isolate](/config/#pooloptions-threads-isolate) +- **命令行终端:** `--poolOptions.threads.isolate` +- **配置:** [poolOptions.threads.isolate](/config/#pooloptions-threads-isolate) 在线程池中隔离测试 (默认值: `true`) ### poolOptions.threads.singleThread -- **CLI:** `--poolOptions.threads.singleThread` -- **Config:** [poolOptions.threads.singleThread](/config/#pooloptions-threads-singlethread) +- **命令行终端:** `--poolOptions.threads.singleThread` +- **配置:** [poolOptions.threads.singleThread](/config/#pooloptions-threads-singlethread) 在单线程内运行测试 (默认值: `false`) ### poolOptions.threads.maxThreads -- **CLI:** `--poolOptions.threads.maxThreads ` -- **Config:** [poolOptions.threads.maxThreads](/config/#pooloptions-threads-maxthreads) +- **命令行终端:** `--poolOptions.threads.maxThreads ` +- **配置:** [poolOptions.threads.maxThreads](/config/#pooloptions-threads-maxthreads) 运行测试的最大线程数或百分比 ### poolOptions.threads.useAtomics -- **CLI:** `--poolOptions.threads.useAtomics` -- **Config:** [poolOptions.threads.useAtomics](/config/#pooloptions-threads-useatomics) +- **命令行终端:** `--poolOptions.threads.useAtomics` +- **配置:** [poolOptions.threads.useAtomics](/config/#pooloptions-threads-useatomics) 使用 Atomics 同步线程。这在某些情况下可以提高性能,但在较旧的 Node 版本中可能会导致 segfault。 (默认值: `false`) ### poolOptions.vmThreads.isolate -- **CLI:** `--poolOptions.vmThreads.isolate` -- **Config:** [poolOptions.vmThreads.isolate](/config/#pooloptions-vmthreads-isolate) +- **命令行终端:** `--poolOptions.vmThreads.isolate` +- **配置:** [poolOptions.vmThreads.isolate](/config/#pooloptions-vmthreads-isolate) 在线程池中隔离测试 (默认值: `true`) ### poolOptions.vmThreads.singleThread -- **CLI:** `--poolOptions.vmThreads.singleThread` -- **Config:** [poolOptions.vmThreads.singleThread](/config/#pooloptions-vmthreads-singlethread) +- **命令行终端:** `--poolOptions.vmThreads.singleThread` +- **配置:** [poolOptions.vmThreads.singleThread](/config/#pooloptions-vmthreads-singlethread) 在单线程内运行测试(默认值:`false`) ### poolOptions.vmThreads.maxThreads -- **CLI:** `--poolOptions.vmThreads.maxThreads ` -- **Config:** [poolOptions.vmThreads.maxThreads](/config/#pooloptions-vmthreads-maxthreads) +- **命令行终端:** `--poolOptions.vmThreads.maxThreads ` +- **配置:** [poolOptions.vmThreads.maxThreads](/config/#pooloptions-vmthreads-maxthreads) 运行测试的最大线程数或百分比 ### poolOptions.vmThreads.useAtomics -- **CLI:** `--poolOptions.vmThreads.useAtomics` -- **Config:** [poolOptions.vmThreads.useAtomics](/config/#pooloptions-vmthreads-useatomics) +- **命令行终端:** `--poolOptions.vmThreads.useAtomics` +- **配置:** [poolOptions.vmThreads.useAtomics](/config/#pooloptions-vmthreads-useatomics) 使用 Atomics 同步线程。这在某些情况下可以提高性能,但在较旧的 Node 版本中可能会导致 segfault。 (默认值: `false`) ### poolOptions.vmThreads.memoryLimit -- **CLI:** `--poolOptions.vmThreads.memoryLimit ` -- **Config:** [poolOptions.vmThreads.memoryLimit](/config/#pooloptions-vmthreads-memorylimit) +- **命令行终端:** `--poolOptions.vmThreads.memoryLimit ` +- **配置:** [poolOptions.vmThreads.memoryLimit](/config/#pooloptions-vmthreads-memorylimit) 虚拟机线程池的内存限制。如果发现内存泄漏,请尝试调整该值。 ### poolOptions.forks.isolate -- **CLI:** `--poolOptions.forks.isolate` -- **Config:** [poolOptions.forks.isolate](/config/#pooloptions-forks-isolate) +- **命令行终端:** `--poolOptions.forks.isolate` +- **配置:** [poolOptions.forks.isolate](/config/#pooloptions-forks-isolate) 在 forks pool 中隔离测试 (默认值: `true`) ### poolOptions.forks.singleFork -- **CLI:** `--poolOptions.forks.singleFork` -- **Config:** [poolOptions.forks.singleFork](/config/#pooloptions-forks-singlefork) +- **命令行终端:** `--poolOptions.forks.singleFork` +- **配置:** [poolOptions.forks.singleFork](/config/#pooloptions-forks-singlefork) 单个子进程内运行测试 (default: `false`) ### poolOptions.forks.maxForks -- **CLI:** `--poolOptions.forks.maxForks ` -- **Config:** [poolOptions.forks.maxForks](/config/#pooloptions-forks-maxforks) +- **命令行终端:** `--poolOptions.forks.maxForks ` +- **配置:** [poolOptions.forks.maxForks](/config/#pooloptions-forks-maxforks) 运行测试的最大进程数 ### poolOptions.vmForks.isolate -- **CLI:** `--poolOptions.vmForks.isolate` -- **Config:** [poolOptions.vmForks.isolate](/config/#pooloptions-vmforks-isolate) +- **命令行终端:** `--poolOptions.vmForks.isolate` +- **配置:** [poolOptions.vmForks.isolate](/config/#pooloptions-vmforks-isolate) 在 forks pool 中隔离测试 (default: `true`) ### poolOptions.vmForks.singleFork -- **CLI:** `--poolOptions.vmForks.singleFork` -- **Config:** [poolOptions.vmForks.singleFork](/config/#pooloptions-vmforks-singlefork) +- **命令行终端:** `--poolOptions.vmForks.singleFork` +- **配置:** [poolOptions.vmForks.singleFork](/config/#pooloptions-vmforks-singlefork) 在单个子进程内运行测试 (default: `false`) ### poolOptions.vmForks.maxForks -- **CLI:** `--poolOptions.vmForks.maxForks ` -- **Config:** [poolOptions.vmForks.maxForks](/config/#pooloptions-vmforks-maxforks) +- **命令行终端:** `--poolOptions.vmForks.maxForks ` +- **配置:** [poolOptions.vmForks.maxForks](/config/#pooloptions-vmforks-maxforks) 运行测试的最大进程数 ### poolOptions.vmForks.memoryLimit -- **CLI:** `--poolOptions.vmForks.memoryLimit ` -- **Config:** [poolOptions.vmForks.memoryLimit](/config/#pooloptions-vmforks-memorylimit) +- **命令行终端:** `--poolOptions.vmForks.memoryLimit ` +- **配置:** [poolOptions.vmForks.memoryLimit](/config/#pooloptions-vmforks-memorylimit) VM forks pool 的内存限制。如果你观察到内存泄漏问题,可以尝试调整这个值。 ### fileParallelism -- **CLI:** `--fileParallelism` -- **Config:** [fileParallelism](/config/#fileparallelism) +- **命令行终端:** `--fileParallelism` +- **配置:** [fileParallelism](/config/#fileparallelism) 是否所有测试文件都应并行运行. 使用 `--no-file-parallelism` 去禁用 (默认值: `true`) ### maxWorkers -- **CLI:** `--maxWorkers ` -- **Config:** [maxWorkers](/config/#maxworkers) +- **命令行终端:** `--maxWorkers ` +- **配置:** [maxWorkers](/config/#maxworkers) 同时并发执行测试任务的最大线程数或百分比 ### environment -- **CLI:** `--environment ` -- **Config:** [environment](/config/#environment) +- **命令行终端:** `--environment ` +- **配置:** [environment](/config/#environment) 如果不在浏览器中运行,则指定运行环境 (默认值: `node`) ### passWithNoTests -- **CLI:** `--passWithNoTests` -- **Config:** [passWithNoTests](/config/#passwithnotests) +- **命令行终端:** `--passWithNoTests` +- **配置:** [passWithNoTests](/config/#passwithnotests) 未发现测试时通过 ### logHeapUsage -- **CLI:** `--logHeapUsage` -- **Config:** [logHeapUsage](/config/#logheapusage) +- **命令行终端:** `--logHeapUsage` +- **配置:** [logHeapUsage](/config/#logheapusage) 在节点中运行时,显示每个测试的堆大小 ### allowOnly -- **CLI:** `--allowOnly` -- **Config:** [allowOnly](/config/#allowonly) +- **命令行终端:** `--allowOnly` +- **配置:** [allowOnly](/config/#allowonly) 允许执行那些被标记为"only"的测试用例或测试套件 (默认值: `!process.env.CI`) ### dangerouslyIgnoreUnhandledErrors -- **CLI:** `--dangerouslyIgnoreUnhandledErrors` -- **Config:** [dangerouslyIgnoreUnhandledErrors](/config/#dangerouslyignoreunhandlederrors) +- **命令行终端:** `--dangerouslyIgnoreUnhandledErrors` +- **配置:** [dangerouslyIgnoreUnhandledErrors](/config/#dangerouslyignoreunhandlederrors) 忽略任何未处理的错误 ### sequence.shuffle.files -- **CLI:** `--sequence.shuffle.files` -- **Config:** [sequence.shuffle.files](/config/#sequence-shuffle-files) +- **命令行终端:** `--sequence.shuffle.files` +- **配置:** [sequence.shuffle.files](/config/#sequence-shuffle-files) 以随机顺序运行文件。如果启用此选项,长时间运行的测试将不会提前开始。 (默认值: `false`) ### sequence.shuffle.tests -- **CLI:** `--sequence.shuffle.tests` -- **Config:** [sequence.shuffle.tests](/config/#sequence-shuffle-tests) +- **命令行终端:** `--sequence.shuffle.tests` +- **配置:** [sequence.shuffle.tests](/config/#sequence-shuffle-tests) 以随机方式运行测试(默认值:`false`) ### sequence.concurrent -- **CLI:** `--sequence.concurrent` -- **Config:** [sequence.concurrent](/config/#sequence-concurrent) +- **命令行终端:** `--sequence.concurrent` +- **配置:** [sequence.concurrent](/config/#sequence-concurrent) 使测试并行运行(默认值:`false`) ### sequence.seed -- **CLI:** `--sequence.seed ` -- **Config:** [sequence.seed](/config/#sequence-seed) +- **命令行终端:** `--sequence.seed ` +- **配置:** [sequence.seed](/config/#sequence-seed) 设置随机化种子。如果 --sequence.shuffle(随机序列)是`false`,则此选项无效。 t 通过 ["Random Seed" page](https://en.wikipedia.org/wiki/Random_seed) 查看更多信息 ### sequence.hooks -- **CLI:** `--sequence.hooks ` -- **Config:** [sequence.hooks](/config/#sequence-hooks) +- **命令行终端:** `--sequence.hooks ` +- **配置:** [sequence.hooks](/config/#sequence-hooks) 更改钩子的执行顺序。 可接受的值有: "stack", "list" and "parallel". 通过 [`sequence.hooks`](https://vitest.dev/config/#sequence-hooks) 查看更多信息 (默认值: `"parallel"`) ### sequence.setupFiles -- **CLI:** `--sequence.setupFiles ` -- **Config:** [sequence.setupFiles](/config/#sequence-setupfiles) +- **命令行终端:** `--sequence.setupFiles ` +- **配置:** [sequence.setupFiles](/config/#sequence-setupfiles) 更改设置文件的执行顺序。可接受的值有 "list" 和 "parallel"。如果设置为"list",将按照定义的顺序运行设置文件。如果设置为 "parallel",将并行运行设置文件(默认值:`"parallel"`)。 ### inspect -- **CLI:** `--inspect [[host:]port]` -- **Config:** [inspect](/config/#inspect) +- **命令行终端:** `--inspect [[host:]port]` +- **配置:** [inspect](/config/#inspect) 启用 Node.js 检查器(默认值:`127.0.0.1:9229`) ### inspectBrk -- **CLI:** `--inspectBrk [[host:]port]` -- **Config:** [inspectBrk](/config/#inspectbrk) +- **命令行终端:** `--inspectBrk [[host:]port]` +- **配置:** [inspectBrk](/config/#inspectbrk) 启用 Node.js 检查器并在测试开始前中断 ### testTimeout -- **CLI:** `--testTimeout ` -- **Config:** [testTimeout](/config/#testtimeout) +- **命令行终端:** `--testTimeout ` +- **配置:** [testTimeout](/config/#testtimeout) 测试的默认超时(毫秒)(默认值:`5000`)。使用 `0` 完全禁用超时。 ### hookTimeout -- **CLI:** `--hookTimeout ` -- **Config:** [hookTimeout](/config/#hooktimeout) +- **命令行终端:** `--hookTimeout ` +- **配置:** [hookTimeout](/config/#hooktimeout) 默认钩子超时(以毫秒为单位)(默认值:`10000`)。使用 `0` 完全禁用超时。 ### bail -- **CLI:** `--bail ` -- **Config:** [bail](/config/#bail) +- **命令行终端:** `--bail ` +- **配置:** [bail](/config/#bail) 当指定数量的测试失败时停止测试执行(默认值:`0`) ### retry -- **CLI:** `--retry ` -- **Config:** [retry](/config/#retry) +- **命令行终端:** `--retry ` +- **配置:** [retry](/config/#retry) 如果测试失败,重试特定次数(默认值: `0`)。 ### diff.aAnnotation -- **CLI:** `--diff.aAnnotation ` -- **Config:** [diff.aAnnotation](/config/#diff-aannotation) +- **命令行终端:** `--diff.aAnnotation ` +- **配置:** [diff.aAnnotation](/config/#diff-aannotation) Annotation for expected lines (default: `Expected`) ### diff.aIndicator -- **CLI:** `--diff.aIndicator ` -- **Config:** [diff.aIndicator](/config/#diff-aindicator) +- **命令行终端:** `--diff.aIndicator ` +- **配置:** [diff.aIndicator](/config/#diff-aindicator) Indicator for expected lines (default: `-`) ### diff.bAnnotation -- **CLI:** `--diff.bAnnotation ` -- **Config:** [diff.bAnnotation](/config/#diff-bannotation) +- **命令行终端:** `--diff.bAnnotation ` +- **配置:** [diff.bAnnotation](/config/#diff-bannotation) Annotation for received lines (default: `Received`) ### diff.bIndicator -- **CLI:** `--diff.bIndicator ` -- **Config:** [diff.bIndicator](/config/#diff-bindicator) +- **命令行终端:** `--diff.bIndicator ` +- **配置:** [diff.bIndicator](/config/#diff-bindicator) Indicator for received lines (default: `+`) ### diff.commonIndicator -- **CLI:** `--diff.commonIndicator ` -- **Config:** [diff.commonIndicator](/config/#diff-commonindicator) +- **命令行终端:** `--diff.commonIndicator ` +- **配置:** [diff.commonIndicator](/config/#diff-commonindicator) Indicator for common lines (default: ` `) ### diff.contextLines -- **CLI:** `--diff.contextLines ` -- **Config:** [diff.contextLines](/config/#diff-contextlines) +- **命令行终端:** `--diff.contextLines ` +- **配置:** [diff.contextLines](/config/#diff-contextlines) Number of lines of context to show around each change (default: `5`) ### diff.emptyFirstOrLastLinePlaceholder -- **CLI:** `--diff.emptyFirstOrLastLinePlaceholder ` -- **Config:** [diff.emptyFirstOrLastLinePlaceholder](/config/#diff-emptyfirstorlastlineplaceholder) +- **命令行终端:** `--diff.emptyFirstOrLastLinePlaceholder ` +- **配置:** [diff.emptyFirstOrLastLinePlaceholder](/config/#diff-emptyfirstorlastlineplaceholder) Placeholder for an empty first or last line (default: `""`) ### diff.expand -- **CLI:** `--diff.expand` -- **Config:** [diff.expand](/config/#diff-expand) +- **命令行终端:** `--diff.expand` +- **配置:** [diff.expand](/config/#diff-expand) Expand all common lines (default: `true`) ### diff.includeChangeCounts -- **CLI:** `--diff.includeChangeCounts` -- **Config:** [diff.includeChangeCounts](/config/#diff-includechangecounts) +- **命令行终端:** `--diff.includeChangeCounts` +- **配置:** [diff.includeChangeCounts](/config/#diff-includechangecounts) Include comparison counts in diff output (default: `false`) ### diff.omitAnnotationLines -- **CLI:** `--diff.omitAnnotationLines` -- **Config:** [diff.omitAnnotationLines](/config/#diff-omitannotationlines) +- **命令行终端:** `--diff.omitAnnotationLines` +- **配置:** [diff.omitAnnotationLines](/config/#diff-omitannotationlines) Omit annotation lines from the output (default: `false`) ### diff.printBasicPrototype -- **CLI:** `--diff.printBasicPrototype` -- **Config:** [diff.printBasicPrototype](/config/#diff-printbasicprototype) +- **命令行终端:** `--diff.printBasicPrototype` +- **配置:** [diff.printBasicPrototype](/config/#diff-printbasicprototype) Print basic prototype Object and Array (default: `true`) ### diff.maxDepth -- **CLI:** `--diff.maxDepth ` -- **Config:** [diff.maxDepth](/config/#diff-maxdepth) +- **命令行终端:** `--diff.maxDepth ` +- **配置:** [diff.maxDepth](/config/#diff-maxdepth) Limit the depth to recurse when printing nested objects (default: `20`) ### diff.truncateThreshold -- **CLI:** `--diff.truncateThreshold ` -- **Config:** [diff.truncateThreshold](/config/#diff-truncatethreshold) +- **命令行终端:** `--diff.truncateThreshold ` +- **配置:** [diff.truncateThreshold](/config/#diff-truncatethreshold) Number of lines to show before and after each change (default: `0`) ### diff.truncateAnnotation -- **CLI:** `--diff.truncateAnnotation ` -- **Config:** [diff.truncateAnnotation](/config/#diff-truncateannotation) +- **命令行终端:** `--diff.truncateAnnotation ` +- **配置:** [diff.truncateAnnotation](/config/#diff-truncateannotation) Annotation for truncated lines (default: `... Diff result is truncated`) ### exclude -- **CLI:** `--exclude ` -- **Config:** [exclude](/config/#exclude) +- **命令行终端:** `--exclude ` +- **配置:** [exclude](/config/#exclude) 测试中排除的其他文件路径匹配模式 ### expandSnapshotDiff -- **CLI:** `--expandSnapshotDiff` -- **Config:** [expandSnapshotDiff](/config/#expandsnapshotdiff) +- **命令行终端:** `--expandSnapshotDiff` +- **配置:** [expandSnapshotDiff](/config/#expandsnapshotdiff) 快照失败时显示完整差异 ### disableConsoleIntercept -- **CLI:** `--disableConsoleIntercept` -- **Config:** [disableConsoleIntercept](/config/#disableconsoleintercept) +- **命令行终端:** `--disableConsoleIntercept` +- **配置:** [disableConsoleIntercept](/config/#disableconsoleintercept) 禁用自动拦截控制台日志(默认值:`false`) ### typecheck.enabled -- **CLI:** `--typecheck.enabled` -- **Config:** [typecheck.enabled](/config/#typecheck-enabled) +- **命令行终端:** `--typecheck.enabled` +- **配置:** [typecheck.enabled](/config/#typecheck-enabled) 在测试的同时启用类型检查(默认值:`false`) ### typecheck.only -- **CLI:** `--typecheck.only` -- **Config:** [typecheck.only](/config/#typecheck-only) +- **命令行终端:** `--typecheck.only` +- **配置:** [typecheck.only](/config/#typecheck-only) 仅运行类型检查测试。这将自动启用类型检查(默认值:`false`) ### typecheck.checker -- **CLI:** `--typecheck.checker ` -- **Config:** [typecheck.checker](/config/#typecheck-checker) +- **命令行终端:** `--typecheck.checker ` +- **配置:** [typecheck.checker](/config/#typecheck-checker) 指定要使用的类型检查器。可用值为 "tsc"和 "vue-tsc "以及一个可执行文件的路径(默认值:`tsc`) ### typecheck.allowJs -- **CLI:** `--typecheck.allowJs` -- **Config:** [typecheck.allowJs](/config/#typecheck-allowjs) +- **命令行终端:** `--typecheck.allowJs` +- **配置:** [typecheck.allowJs](/config/#typecheck-allowjs) 允许对 JavaScript 文件进行类型检查。默认值取自 tsconfig.json ### typecheck.ignoreSourceErrors -- **CLI:** `--typecheck.ignoreSourceErrors` -- **Config:** [typecheck.ignoreSourceErrors](/config/#typecheck-ignoresourceerrors) +- **命令行终端:** `--typecheck.ignoreSourceErrors` +- **配置:** [typecheck.ignoreSourceErrors](/config/#typecheck-ignoresourceerrors) 忽略源文件中的类型错误 ### typecheck.tsconfig -- **CLI:** `--typecheck.tsconfig ` -- **Config:** [typecheck.tsconfig](/config/#typecheck-tsconfig) +- **命令行终端:** `--typecheck.tsconfig ` +- **配置:** [typecheck.tsconfig](/config/#typecheck-tsconfig) 自定义 tsconfig 文件的路径 ### typecheck.spawnTimeout -- **CLI:** `--typecheck.spawnTimeout