From f8d1d1ce1f56f0364bd46b99b01da7e095ae7a1a Mon Sep 17 00:00:00 2001 From: wumingdao Date: Thu, 1 Jan 2026 13:41:44 +0800 Subject: [PATCH 01/31] docs(cn): translate comments and missing content MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - api/browser/interactivity.md: translate WebdriverIO comment - api/browser/locators.md: translate label comments - guide/mocking/modules.md: translate code comments - config/browser.md: translate comparators section - config/experimental.md: complete translation - api/expect.md: translate missing comments and schemaMatching 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- api/advanced/plugin.md | 13 ++-- api/advanced/reporters.md | 7 +- api/advanced/test-case.md | 6 +- api/advanced/test-suite.md | 14 ++-- api/advanced/vitest.md | 16 ++--- api/browser/interactivity.md | 22 +++--- api/browser/locators.md | 21 +++--- api/expect-typeof.md | 11 ++- api/expect.md | 29 ++++---- api/index.md | 13 ++-- config/browser.md | 53 +++++++-------- config/experimental.md | 79 +++++++++++----------- config/index.md | 12 ++-- config/onstacktrace.md | 14 ++-- config/resolvesnapshotpath.md | 10 +-- guide/browser/component-testing.md | 22 +++--- guide/browser/index.md | 20 +++--- guide/browser/visual-regression-testing.md | 49 +++++++------- guide/comparisons.md | 30 ++++---- guide/features.md | 5 +- guide/migration.md | 15 ++-- guide/mocking/modules.md | 20 +++--- guide/open-telemetry.md | 58 ++++++++-------- guide/parallelism.md | 3 +- guide/profiling-test-performance.md | 15 ++-- guide/test-context.md | 7 +- 26 files changed, 271 insertions(+), 293 deletions(-) diff --git a/api/advanced/plugin.md b/api/advanced/plugin.md index 07303230..37176aba 100644 --- a/api/advanced/plugin.md +++ b/api/advanced/plugin.md @@ -124,7 +124,6 @@ vitest.config.project.push('my-project-name') 请注意,这也将继承 `name` - Vitest 不允许多个项目使用相同的名称,因此这将引发错误。请确保我们指定了不同的名称。我们可以通过 `project.name` 属性访问当前名称,并且所有使用的名称都可以在 `vitest.projects` 数组中找到。 ::: - ### experimental_defineCacheKeyGenerator 4.0.11 {#definecachekeygenerator} ```ts @@ -139,11 +138,11 @@ function experimental_defineCacheKeyGenerator( ): void ``` -Define a generator that will be applied before hashing the cache key. +定义一个生成器,它将在哈希缓存键之前应用。 -Use this to make sure Vitest generates correct hash. It is a good idea to define this function if your plugin can be registered with different options. +使用此方法确保 Vitest 生成正确的哈希。如果你的插件可以使用不同的选项注册,定义此函数是一个好主意。 -This is called only if [`experimental.fsModuleCache`](/config/experimental#experimental-fsmodulecache) is defined. +仅当定义了 [`experimental.fsModuleCache`](/config/experimental#experimental-fsmodulecache) 时才会调用此方法。 ```ts interface PluginOptions { @@ -162,8 +161,8 @@ export function plugin(options: PluginOptions) { }, configureVitest({ experimental_defineCacheKeyGenerator }) { experimental_defineCacheKeyGenerator(() => { - // since these options affect the transform result, - // return them together as a unique string + // 由于这些选项会影响转换结果, + // 将它们作为唯一字符串一起返回 return options.replacePropertyKey + options.replacePropertyValue }) } @@ -171,4 +170,4 @@ export function plugin(options: PluginOptions) { } ``` -If `false` is returned, the module will not be cached on the file system. +如果返回 `false`,模块将不会缓存在文件系统上。 diff --git a/api/advanced/reporters.md b/api/advanced/reporters.md index a76397e3..0cc11d73 100644 --- a/api/advanced/reporters.md +++ b/api/advanced/reporters.md @@ -330,7 +330,6 @@ onTestAnnotate 是与 [`context.annotate`](/guide/test-context#annotate) 方法 如果在注解中指定了文件路径, Vitest 会将附件保存到一个独立的目录(该目录通过 [`attachmentsDir`](/config/#attachmentsdir) 配置),并自动更新 path 属性,使其指向存储后的文件位置。 - ## onTestCaseArtifactRecord 4.0.11 {#ontestcaseartifactrecord} ```ts @@ -340,8 +339,8 @@ function onTestCaseArtifactRecord( ): Awaitable ``` -The `onTestCaseArtifactRecord` hook is associated with the [`recordArtifact`](/api/advanced/artifacts#recordartifact) utility. When `recordArtifact` is invoked, Vitest serialises it and sends the same attachment to the main thread where reporter can interact with it. +`onTestCaseArtifactRecord` 钩子与 [`recordArtifact`](/api/advanced/artifacts#recordartifact) 工具相关联。当调用 `recordArtifact` 时,Vitest 会将其序列化并将相同的附件发送到主线程,报告器可以在那里与其交互。 -If the path is specified, Vitest stores it in a separate directory (configured by [`attachmentsDir`](/config/#attachmentsdir)) and modifies the `path` property to reference it. +如果指定了路径,Vitest 会将其存储在单独的目录中(由 [`attachmentsDir`](/config/#attachmentsdir) 配置),并修改 `path` 属性以引用它。 -Note: annotations, [even though they're built on top of this feature](/api/advanced/artifacts#relationship-with-annotations), won't hit this hook and won't appear in the `task.artifacts` array for backwards compatibility reasons until the next major version. +注意:注解,[即使它们是基于此功能构建的](/api/advanced/artifacts#relationship-with-annotations),出于向后兼容性原因,在下一个主要版本之前不会触发此钩子,也不会出现在 `task.artifacts` 数组中。 diff --git a/api/advanced/test-case.md b/api/advanced/test-case.md index c7add2e5..46af190a 100644 --- a/api/advanced/test-case.md +++ b/api/advanced/test-case.md @@ -265,14 +265,14 @@ interface TestDiagnostic { ::: info 如果测试尚未被安排运行,`diagnostic()` 将返回 `undefined`。 ::: - + ## annotations ```ts function annotations(): ReadonlyArray ``` -[Test annotations](/guide/test-annotations) added via the [`task.annotate`](/guide/test-context#annotate) API during the test execution. +在测试执行期间通过 [`task.annotate`](/guide/test-context#annotate) API 添加的[测试注释](/guide/test-annotations)。 ## artifacts 4.0.11 {#artifacts} @@ -280,4 +280,4 @@ function annotations(): ReadonlyArray function artifacts(): ReadonlyArray ``` -[Test artifacts](/api/advanced/artifacts) recorded via the `recordArtifact` API during the test execution. +在测试执行期间通过 `recordArtifact` API 记录的[测试工件](/api/advanced/artifacts)。 diff --git a/api/advanced/test-suite.md b/api/advanced/test-suite.md index 949c4240..2de68b60 100644 --- a/api/advanced/test-suite.md +++ b/api/advanced/test-suite.md @@ -63,13 +63,13 @@ ID 的格式如下: ::: tip 你可以使用 `vitest/node` 中的 `generateFileHash` 函数生成文件哈希,该函数自 Vitest 3 起可用: - + ```ts import { generateFileHash } from 'vitest/node' const hash = generateFileHash( - '/file/path.js', // relative path - undefined // the project name or `undefined` is not set + '/file/path.js', // 相对路径 + undefined // 项目名称,如果未设置则为 `undefined` ) ``` @@ -199,19 +199,19 @@ describe('collection failed', () => { function meta(): TaskMeta ``` 在执行或收集过程中附加到套件的自定义[元数据](/api/advanced/metadata)。在测试运行期间,可以通过向 `task.meta` 对象分配属性来附加 meta: - + ```ts {7,12} import { test } from 'vitest' import { getCurrentSuite } from 'vitest/suite' describe('the validation works correctly', () => { - // assign "decorated" during collection + // 在收集期间分配 "decorated" const { suite } = getCurrentSuite() suite!.meta.decorated = true test('some test', ({ task }) => { - // 在试运行期间指定 “decorated”,它将可用 - // 仅在 onTestCaseReady hook + // 在测试运行期间分配 "decorated",它将可用 + // 仅在 onTestCaseReady hook 中 task.suite.meta.decorated = false }) }) diff --git a/api/advanced/vitest.md b/api/advanced/vitest.md index 87c9e845..701092ad 100644 --- a/api/advanced/vitest.md +++ b/api/advanced/vitest.md @@ -463,8 +463,8 @@ function onCancel(fn: (reason: CancelReason) => Awaitable): () => void 注册一个处理程序,当测试运行被 [`vitest.cancelCurrentRun`](#cancelcurrentrun) 取消时调用。 -::: warning EXPERIMENTAL -Since 4.0.10, `onCancel` returns a teardown function that will remove the listener. +::: warning 实验性 +自 4.0.10 起,`onCancel` 返回一个清理函数,用于移除监听器。 ::: ## onClose @@ -611,8 +611,8 @@ function experimental_parseSpecifications( } ): Promise ``` - -This method will [collect tests](#parsespecification) from an array of specifications. By default, Vitest will run only `os.availableParallelism()` number of specifications at a time to reduce the potential performance degradation. You can specify a different number in a second argument. + +此方法将从规范数组中 [收集测试](#parsespecification)。默认情况下,Vitest 一次只运行 `os.availableParallelism()` 数量的规范,以减少潜在的性能下降。你可以在第二个参数中指定不同的数字。 ## experimental_clearCache 4.0.11 {#clearcache} @@ -620,7 +620,7 @@ This method will [collect tests](#parsespecification) from an array of specifica function experimental_clearCache(): Promise ``` -Deletes all Vitest caches, including [`experimental.fsModuleCache`](/config/experimental#experimental-fsmodulecache). +删除所有 Vitest 缓存,包括 [`experimental.fsModuleCache`](/config/experimental#experimental-fsmodulecache)。 ## experimental_getSourceModuleDiagnostic 4.0.15 {#getsourcemodulediagnostic} @@ -631,7 +631,7 @@ export function experimental_getSourceModuleDiagnostic( ): Promise ``` -::: details Types +::: details 类型 ```ts export interface ModuleDefinitionLocation { line: number @@ -673,8 +673,8 @@ export interface SourceModuleDiagnostic { ``` ::: -Returns module's diagnostic. If [`testModule`](/api/advanced/test-module) is not provided, `selfTime` and `totalTime` will be aggregated across all tests that were running the last time. If the module was not transformed or executed, the diagnostic will be empty. +返回模块的诊断信息。如果未提供 [`testModule`](/api/advanced/test-module),`selfTime` 和 `totalTime` 将汇总上次运行的所有测试。如果模块未被转换或执行,诊断信息将为空。 ::: warning -At the moment, the [browser](/guide/browser/) modules are not supported. +目前不支持 [浏览器](/guide/browser/) 模块。 ::: diff --git a/api/browser/interactivity.md b/api/browser/interactivity.md index 0a8957f0..ab344ef1 100644 --- a/api/browser/interactivity.md +++ b/api/browser/interactivity.md @@ -61,28 +61,28 @@ test('clicks on an element', async () => { // 或者你可以直接从定位器上访问 await logo.click() - // With WebdriverIO, this uses either ElementClick (with no arguments) or - // actions (with arguments). Use an empty object to force the use of actions. + // 使用 WebdriverIO 时,这会使用 ElementClick(无参数时)或 + // actions(有参数时)。使用空对象可以强制使用 actions。 await logo.click({}) }) ``` - -### Clicking with a modifier -With either WebdriverIO or Playwright: +### 使用修饰键点击 + +使用 WebdriverIO 或 Playwright: ```ts await userEvent.keyboard('{Shift>}') -// By using an empty object as the option, this opts in to using a chain of actions -// instead of an ElementClick in webdriver. -// Firefox has a bug that makes this necessary. -// Follow https://bugzilla.mozilla.org/show_bug.cgi?id=1456642 to know when this -// will be fixed. +// 通过使用空对象作为选项,这会选择使用一系列操作 +// 而不是 webdriver 中的 ElementClick。 +// Firefox 有一个 bug 使这成为必要。 +// 关注 https://bugzilla.mozilla.org/show_bug.cgi?id=1456642 以了解何时 +// 修复此问题。 await userEvent.click(element, {}) await userEvent.keyboard('{/Shift}') ``` -With Playwright: +使用 Playwright: ```ts await userEvent.click(element, { modifiers: ['Shift'] }) ``` diff --git a/api/browser/locators.md b/api/browser/locators.md index f9cf47ff..67eba258 100644 --- a/api/browser/locators.md +++ b/api/browser/locators.md @@ -245,18 +245,18 @@ function getByLabelText( -// Wrapper labels +// 包裹式标签 -// Wrapper labels where the label text is in another child element +// 标签文本在另一个子元素中的包裹式标签 -// aria-label attributes -// Take care because this is not a label that users can see on the page, -// so the purpose of your input must be obvious to visual users. +// aria-label 属性 +// 请注意,这不是用户在页面上能看到的标签, +// 因此输入框的用途必须对视觉用户来说是显而易见的。 ``` @@ -784,7 +784,7 @@ function screenshot(options?: LocatorScreenshotOptions & { base64?: false }): Pr 你可以使用 `path` 选项指定屏幕截图的保存位置,该选项相对于当前测试文件。如果未设置 `path` 选项,Vitest 将默认使用 [`browser.screenshotDirectory`](/config/browser/screenshotdirectory)(默认为 `__screenshot__`),并结合文件名和测试名来确定屏幕截图的文件路径。 如果你还需要屏幕截图的内容,可以指定 `base64: true` 以返回屏幕截图的 base64 编码内容以及保存路径。 - + ```ts import { page } from 'vitest/browser' @@ -794,10 +794,10 @@ const path = await button.screenshot() const { path, base64 } = await button.screenshot({ path: './button-click-me.png', - base64: true, // also return base64 string + base64: true, // 同时返回 base64 字符串 }) -// path - fullpath to the screenshot -// bas64 - base64 encoded string of the screenshot +// path - 屏幕截图的完整路径 +// base64 - 屏幕截图的 base64 编码字符串 ``` ::: warning WARNING 3.2.0 @@ -959,8 +959,7 @@ test('works correctly', async () => { ### length -This getter returns a number of elements that this locator is matching. It is equivalent to calling `locator.elements().length`. -此属性返回当前定位器匹配的元素数量,等效于调用 g `locator.elements().length`。 +此属性返回当前定位器匹配的元素数量,等效于调用 `locator.elements().length`。 参考以下 DOM 结构: diff --git a/api/expect-typeof.md b/api/expect-typeof.md index 9fcbb5d6..efe8b7dc 100644 --- a/api/expect-typeof.md +++ b/api/expect-typeof.md @@ -553,23 +553,22 @@ expectTypeOf(obj).toHaveProperty('b').toBeString() expectTypeOf(obj).toHaveProperty('a').not.toBeString() ``` - ## branded -- **Type:** `ExpectTypeOf` +- **类型:** `ExpectTypeOf` -You can use `.branded` to allow type assertions to succeed for types that are semantically equivalent but differ in representation. +你可以使用 `.branded` 来允许类型断言对语义上等效但表示形式不同的类型成功。 ```ts import { expectTypeOf } from 'vitest' -// Without .branded, this fails even though the types are effectively the same +// 没有 .branded,即使类型实际上相同,这也会失败 expectTypeOf<{ a: { b: 1 } & { c: 1 } }>().toEqualTypeOf<{ a: { b: 1; c: 1 } }>() -// With .branded, the assertion succeeds +// 使用 .branded,断言成功 expectTypeOf<{ a: { b: 1 } & { c: 1 } }>().branded.toEqualTypeOf<{ a: { b: 1; c: 1 } }>() ``` ::: warning -This helper comes at a performance cost and can cause the TypeScript compiler to 'give up' if used with excessively deep types. Use it sparingly and only when necessary. +此辅助函数会带来性能成本,如果用于过深的类型,可能会导致 TypeScript 编译器"放弃"。请谨慎使用,仅在必要时使用。 ::: diff --git a/api/expect.md b/api/expect.md index 57a145ed..34027127 100644 --- a/api/expect.md +++ b/api/expect.md @@ -189,8 +189,7 @@ test('stocks are the same', () => { - **类型:** `(value: number, numDigits?: number) => Awaitable` - -Use `toBeCloseTo` to compare floating-point numbers. The optional `numDigits` argument limits the number of digits to check _after_ the decimal point. The default for `numDigits` is 2. For example: +使用 `toBeCloseTo` 来比较浮点数。可选的 `numDigits` 参数用于限制小数点_后_要检查的位数。`numDigits` 的默认值为 2。例如: ```ts import { expect, test } from 'vitest' @@ -380,13 +379,13 @@ test('getApplesCount has some unusual side effects...', () => { ``` ## toBeOneOf - -- **Type:** `(sample: Array | Set) => any` -`toBeOneOf` asserts if a value matches any of the values in the provided array or set. +- **类型:** `(sample: Array | Set) => any` -::: warning EXPERIMENTAL -Providing a `Set` is an experimental feature and may change in a future release. +`toBeOneOf` 断言一个值是否匹配提供的数组或集合中的任意一个值。 + +::: warning 实验性功能 +提供 `Set` 是一个实验性功能,可能会在未来版本中发生变化。 ::: ```ts @@ -648,7 +647,7 @@ test('toHaveLength', () => { expect('abc').toHaveLength(3) expect([1, 2, 3]).toHaveLength(3) - expect('').not.toHaveLength(3) // doesn't have .length of 3 + expect('').not.toHaveLength(3) // 长度不为 3 expect({ length: 3 }).toHaveLength(3) }) ``` @@ -707,7 +706,7 @@ test('John Doe Invoice', () => { // 将键名包裹在数组中,避免其被解析为深层引用 expect(invoice).toHaveProperty(['P.O'], '12345') - // Deep equality of object property + // 对象属性的深度相等 expect(invoice).toHaveProperty('items[0]', { type: 'apples', quantity: 10 }) }) ``` @@ -723,7 +722,7 @@ import { expect, test } from 'vitest' test('top fruits', () => { expect('top fruits include apple, orange and grape').toMatch(/apple/) - expect('applefruits').toMatch('fruit') // toMatch also accepts a string + expect('applefruits').toMatch('fruit') // toMatch 也接受字符串 }) ``` @@ -770,8 +769,8 @@ test('invoice has john personal details', () => { expect(johnInvoice).toMatchObject(johnDetails) }) -test('the number of elements must match exactly', () => { - // Assert that an array of object matches +test('元素数量必须完全匹配', () => { + // 断言对象数组匹配 expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([ { foo: 'bar' }, { baz: 1 }, @@ -1234,7 +1233,7 @@ test('spy function returns bananas on a last call', () => { 我们可以调用这个断言来检查函数是否在特定的调用中成功返回了带有特定参数的值。需要将一个 spy 函数传递给 `expect`。 -The count starts at 1. So, to check the second entry, you would write `.toHaveNthReturnedWith(2, ...)`. +计数从 1 开始。因此,要检查第二个条目,你需要写 `.toHaveNthReturnedWith(2, ...)`。 ```ts import { expect, test, vi } from 'vitest' @@ -1713,9 +1712,9 @@ test('variety ends with "re"', () => { ## expect.schemaMatching -- **Type:** `(expected: StandardSchemaV1) => any` +- **类型:** `(expected: StandardSchemaV1) => any` -When used with an equality check, this asymmetric matcher will return `true` if the value matches the provided schema. The schema must implement the [Standard Schema v1](https://standardschema.dev/) specification. +当与相等性检查一起使用时,如果值与提供的 schema 匹配,此非对称匹配器将返回 `true`。schema 必须实现 [Standard Schema v1](https://standardschema.dev/) 规范。 ```ts import { expect, test } from 'vitest' diff --git a/api/index.md b/api/index.md index 0431e9c0..c00e44c0 100644 --- a/api/index.md +++ b/api/index.md @@ -427,8 +427,8 @@ test.each([ expect(a + b).toBe(expected) }) ``` - -You can also access Object attributes with `.`, if you are using objects as arguments: + +如果使用对象作为参数,你也可以使用 `.` 来访问对象属性: ```ts test.each` @@ -440,14 +440,14 @@ You can also access Object attributes with `.`, if you are using objects as argu expect(a.val + b).toBe(expected) }) - // this will return + // 这将返回 // ✓ add(1, b) -> 1b // ✓ add(2, b) -> 2b // ✓ add(3, b) -> 3b ``` -* First row should be column names, separated by `|`; -* One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax. +* 第一行应为列名,用 `|` 分隔; +* 使用 `${value}` 语法,以模板字面表达式的形式提供后面一行或多行数据。 ```ts import { expect, test } from 'vitest' @@ -1221,9 +1221,8 @@ afterEach(async () => { 在这里,`afterEach` 可确保在每次测试运行后清除测试数据。 - ::: tip -You can also use [`onTestFinished`](#ontestfinished) during the test execution to cleanup any state after the test has finished running. +你也可以在测试执行期间使用 [`onTestFinished`](#ontestfinished) 来在测试运行完成后清理任何状态。 ::: ### beforeAll diff --git a/config/browser.md b/config/browser.md index dd56ae03..84390037 100644 --- a/config/browser.md +++ b/config/browser.md @@ -1,6 +1,5 @@ - --- -title: Browser Config Reference | Config +title: 浏览器配置参考 | 配置 outline: deep --- # 浏览器配置参考 {#browser-config-reference} @@ -56,8 +55,7 @@ export default defineConfig({ 定义多个浏览器设置。每个配置必须至少有一个 `browser` 字段。 - -You can specify most of the [project options](/config/) (not marked with a icon) and some of the `browser` options like `browser.testerHtmlPath`. +你可以指定大多数 [项目选项](/config/)(未标记 图标的)和一些 `browser` 选项,如 `browser.testerHtmlPath`。 ::: warning 每个浏览器配置都从根配置继承选项: @@ -105,17 +103,16 @@ export default defineConfig({ 在 `headless` 模式下运行浏览器。如果我们在 CI 中运行 Vitest,则默认启用此模式。 - ## browser.isolate - **类型:** `boolean` -- **Default:** the same as [`--isolate`](/config/#isolate) +- **默认值:** 与 [`--isolate`](/config/#isolate) 相同 - **CLI:** `--browser.isolate`, `--browser.isolate=false` 在单独的 iframe 中运行每个测试。 -::: danger DEPRECATED -This option is deprecated. Use [`isolate`](/config/#isolate) instead. +::: danger 已弃用 +此选项已弃用。请改用 [`isolate`](/config/#isolate)。 ::: ## browser.testerHtmlPath @@ -491,16 +488,16 @@ resolveDiffPath: ({ arg, attachmentsDir, browserName, ext, root, testFileName }) #### browser.expect.toMatchScreenshot.comparators -- **Type:** `Record` +- **类型:** `Record` -Register custom screenshot comparison algorithms, like [SSIM](https://en.wikipedia.org/wiki/Structural_similarity_index_measure) or other perceptual similarity metrics. +注册自定义截图比较算法,如 [SSIM](https://en.wikipedia.org/wiki/Structural_similarity_index_measure) 或其他感知相似度指标。 -To create a custom comparator, you need to register it in your config. If using TypeScript, declare its options in the `ScreenshotComparatorRegistry` interface. +要创建自定义比较器,你需要在配置中注册它。如果使用 TypeScript,请在 `ScreenshotComparatorRegistry` 接口中声明其选项。 ```ts import { defineConfig } from 'vitest/config' -// 1. Declare the comparator's options type +// 1. 声明比较器的选项类型 declare module 'vitest/browser' { interface ScreenshotComparatorRegistry { myCustomComparator: { @@ -510,7 +507,7 @@ declare module 'vitest/browser' { } } -// 2. Implement the comparator +// 2. 实现比较器 export default defineConfig({ test: { browser: { @@ -521,12 +518,12 @@ export default defineConfig({ reference, actual, { - createDiff, // always provided by Vitest + createDiff, // 始终由 Vitest 提供 sensitivity = 0.01, ignoreColors = false, } ) => { - // ...algorithm implementation + // ...算法实现 return { pass, diff, message } }, }, @@ -537,7 +534,7 @@ export default defineConfig({ }) ``` -Then use it in your tests: +然后在测试中使用它: ```ts await expect(locator).toMatchScreenshot({ @@ -574,22 +571,22 @@ type Comparator = ( message: string | null } ``` - -The `reference` and `actual` images are decoded using the appropriate codec (currently only PNG). The `data` property is a flat `TypedArray` (`Buffer`, `Uint8Array`, or `Uint8ClampedArray`) containing pixel data in RGBA format: -- **4 bytes per pixel**: red, green, blue, alpha (from `0` to `255` each) -- **Row-major order**: pixels are stored left-to-right, top-to-bottom -- **Total length**: `width × height × 4` bytes -- **Alpha channel**: always present. Images without transparency have alpha values set to `255` (fully opaque) +`reference` 和 `actual` 图像使用适当的编解码器(目前仅支持 PNG)进行解码。`data` 属性是一个扁平的 `TypedArray`(`Buffer`、`Uint8Array` 或 `Uint8ClampedArray`),包含 RGBA 格式的像素数据: -::: tip Performance Considerations -The `createDiff` option indicates whether a diff image is needed. During [stable screenshot detection](/guide/browser/visual-regression-testing#how-visual-tests-work), Vitest calls comparators with `createDiff: false` to avoid unnecessary work. +- **每像素 4 字节**:红色、绿色、蓝色、alpha(每个从 `0` 到 `255`) +- **行主序**:像素从左到右、从上到下存储 +- **总长度**:`width × height × 4` 字节 +- **Alpha 通道**:始终存在。没有透明度的图像的 alpha 值设置为 `255`(完全不透明) -**Respect this flag to keep your tests fast**. +::: tip 性能考虑 +`createDiff` 选项指示是否需要差异图像。在 [稳定截图检测](/guide/browser/visual-regression-testing#how-visual-tests-work) 期间,Vitest 使用 `createDiff: false` 调用比较器以避免不必要的工作。 + +**尊重此标志以保持测试快速**。 ::: -::: warning Handle Missing Options -The `options` parameter in `toMatchScreenshot()` is optional, so users might not provide all your comparator options. Always make them optional with default values: +::: warning 处理缺失选项 +`toMatchScreenshot()` 中的 `options` 参数是可选的,因此用户可能不会提供所有比较器选项。始终使用默认值使它们成为可选的: ```ts myCustomComparator: ( @@ -597,7 +594,7 @@ myCustomComparator: ( actual, { createDiff, threshold = 0.1, maxDiff = 100 }, ) => { - // ...comparison logic + // ...比较逻辑 } ``` ::: diff --git a/config/experimental.md b/config/experimental.md index 7d3c51e7..45dd890e 100644 --- a/config/experimental.md +++ b/config/experimental.md @@ -2,7 +2,6 @@ title: experimental | Config outline: deep --- - # experimental @@ -12,28 +11,28 @@ outline: deep 请将关于此功能反馈提交至 [GitHub Discussion](https://github.com/vitest-dev/vitest/discussions/9221)。 ::: -- **Type:** `boolean` -- **Default:** `false` +- **类型:** `boolean` +- **默认值:** `false` -Enabling this option allows Vitest to keep cached modules on the file system, making tests run faster between reruns. +启用此选项允许 Vitest 将缓存的模块保存在文件系统上,使测试在重新运行之间运行得更快。 -You can delete the old cache by running [`vitest --clearCache`](/guide/cli#clearcache). +你可以通过运行 [`vitest --clearCache`](/guide/cli#clearcache) 来删除旧缓存。 -::: warning BROWSER SUPPORT -At the moment, this option does not affect [the browser](/guide/browser/). +::: warning 浏览器支持 +目前,此选项不影响[浏览器](/guide/browser/)。 ::: -You can debug if your modules are cached by running vitest with a `DEBUG=vitest:cache:fs` environment variable: +你可以通过使用 `DEBUG=vitest:cache:fs` 环境变量运行 vitest 来调试模块是否被缓存: ```shell DEBUG=vitest:cache:fs vitest --experimental.fsModuleCache ``` -### Known Issues +### 已知问题 {#known-issues} -Vitest creates persistent file hash based on file content, its id, vite's environment configuration and coverage status. Vitest tries to use as much information it has about the configuration, but it is still incomplete. At the moment, it is not possible to track your plugin options because there is no standard interface for it. +Vitest 基于文件内容、其 id、vite 的环境配置和覆盖率状态创建持久文件哈希。Vitest 尝试使用它拥有的关于配置的尽可能多的信息,但它仍然不完整。目前,无法跟踪你的插件选项,因为没有标准接口。 -If you have a plugin that relies on things outside the file content or the public configuration (like reading another file or a folder), it's possible that the cache will get stale. To workaround that, you can define a [cache key generator](/api/advanced/plugin#definecachekeygenerator) to specify dynamic option or to opt-out of caching for that module: +如果你有一个依赖于文件内容或公共配置之外的内容(如读取另一个文件或文件夹)的插件,缓存可能会变得陈旧。要解决这个问题,你可以定义一个[缓存键生成器](/api/advanced/plugin#definecachekeygenerator)来指定动态选项或选择不缓存该模块: ```js [vitest.config.js] import { defineConfig } from 'vitest/config' @@ -44,12 +43,12 @@ export default defineConfig({ name: 'vitest-cache', configureVitest({ experimental_defineCacheKeyGenerator }) { experimental_defineCacheKeyGenerator(({ id, sourceCode }) => { - // never cache this id + // 永不缓存此 id if (id.includes('do-not-cache')) { return false } - // cache this file based on the value of a dynamic variable + // 基于动态变量的值缓存此文件 if (sourceCode.includes('myDynamicVar')) { return process.env.DYNAMIC_VAR_VALUE } @@ -65,9 +64,9 @@ export default defineConfig({ }) ``` -If you are a plugin author, consider defining a [cache key generator](/api/advanced/plugin#definecachekeygenerator) in your plugin if it can be registered with different options that affect the transform result. +如果你是插件作者,如果你的插件可以使用影响转换结果的不同选项进行注册,请考虑在插件中定义一个[缓存键生成器](/api/advanced/plugin#definecachekeygenerator)。 -On the other hand, if your plugin should not affect the cache key, you can opt-out by setting `api.vitest.experimental.ignoreFsModuleCache` to `true`: +另一方面,如果你的插件不应该影响缓存键,你可以通过将 `api.vitest.experimental.ignoreFsModuleCache` 设置为 `true` 来选择退出: ```js [vitest.config.js] import { defineConfig } from 'vitest/config' @@ -93,18 +92,18 @@ export default defineConfig({ }) ``` -Note that you can still define the cache key generator even the plugin opt-out of module caching. +请注意,即使插件选择退出模块缓存,你仍然可以定义缓存键生成器。 ## experimental.fsModuleCachePath 4.0.11 {#experimental-fsmodulecachepath} -- **Type:** `string` -- **Default:** `'node_modules/.experimental-vitest-cache'` +- **类型:** `string` +- **默认值:** `'node_modules/.experimental-vitest-cache'` -Directory where the file system cache is located. +文件系统缓存所在的目录。 -By default, Vitest will try to find the workspace root and store the cache inside the `node_modules` folder. The root is based on your package manager's lockfile (for example, `.package-lock.json`, `.yarn-state.yml`, `.pnpm/lock.yaml` and so on). +默认情况下,Vitest 会尝试找到工作区根目录并将缓存存储在 `node_modules` 文件夹中。根目录基于你的包管理器的锁文件(例如,`.package-lock.json`、`.yarn-state.yml`、`.pnpm/lock.yaml` 等)。 -At the moment, Vitest ignores the [test.cache.dir](/config/cache) or [cacheDir](https://vite.dev/config/shared-options#cachedir) options completely and creates a separate folder. +目前,Vitest 完全忽略 [test.cache.dir](/config/cache) 或 [cacheDir](https://vite.dev/config/shared-options#cachedir) 选项,并创建一个单独的文件夹。 ## experimental.openTelemetry 4.0.11 {#experimental-opentelemetry} @@ -112,35 +111,35 @@ At the moment, Vitest ignores the [test.cache.dir](/config/cache) or [cacheDir]( 请将关于此功能反馈提交至 [GitHub Discussion](https://github.com/vitest-dev/vitest/discussions/9222)。 ::: -- **Type:** +- **类型:** ```ts interface OpenTelemetryOptions { enabled: boolean /** - * A path to a file that exposes an OpenTelemetry SDK for Node.js. + * 暴露 Node.js OpenTelemetry SDK 的文件路径。 */ sdkPath?: string /** - * A path to a file that exposes an OpenTelemetry SDK for the browser. + * 暴露浏览器 OpenTelemetry SDK 的文件路径。 */ browserSdkPath?: string } ``` -- **Default:** `{ enabled: false }` +- **默认值:** `{ enabled: false }` -This option controls [OpenTelemetry](https://opentelemetry.io/) support. Vitest imports the SDK file in the main thread and before every test file, if `enabled` is set to `true`. +此选项控制 [OpenTelemetry](https://opentelemetry.io/) 支持。如果 `enabled` 设置为 `true`,Vitest 会在主线程中以及每个测试文件之前导入 SDK 文件。 -::: danger PERFORMANCE CONCERNS -OpenTelemetry may significantly impact Vitest performance; enable it only for local debugging. +::: danger 性能注意事项 +OpenTelemetry 可能会显著影响 Vitest 性能;仅在本地调试时启用它。 ::: -You can use a [custom service](/guide/open-telemetry) together with Vitest to pinpoint which tests or files are slowing down your test suite. +你可以将[自定义服务](/guide/open-telemetry)与 Vitest 一起使用,以精确定位哪些测试或文件正在拖慢你的测试套件。 -For browser mode, see the [Browser Mode](/guide/open-telemetry#browser-mode) section of the OpenTelemetry guide. +对于浏览器模式,请参阅 OpenTelemetry 指南的[浏览器模式](/guide/open-telemetry#browser-mode)部分。 -An `sdkPath` is resolved relative to the [`root`](/config/root) of the project and should point to a module that exposes a started SDK instance as a default export. For example: +`sdkPath` 相对于项目的 [`root`](/config/root) 解析,应指向一个将已启动的 SDK 实例作为默认导出暴露的模块。例如: ::: code-group ```js [otel.js] @@ -174,7 +173,7 @@ export default defineConfig({ ::: ::: warning -It's important that Node can process `sdkPath` content because it is not transformed by Vitest. See [the guide](/guide/open-telemetry) on how to work with OpenTelemetry inside of Vitest. +重要的是 Node 能够处理 `sdkPath` 内容,因为它不会被 Vitest 转换。请参阅[指南](/guide/open-telemetry)了解如何在 Vitest 中使用 OpenTelemetry。 ::: ## experimental.printImportBreakdown 4.0.15 {#experimental-printimportbreakdown} @@ -183,18 +182,18 @@ It's important that Node can process `sdkPath` content because it is not transfo 请将关于此功能反馈提交至 [GitHub Discussion](https://github.com/vitest-dev/vitest/discussions/9224)。 ::: -- **Type:** `boolean` -- **Default:** `false` +- **类型:** `boolean` +- **默认值:** `false` -Show import duration breakdown after tests have finished running. This option only works with [`default`](/guide/reporters#default), [`verbose`](/guide/reporters#verbose), or [`tree`](/guide/reporters#tree) reporters. +在测试运行完成后显示导入耗时分解。此选项仅适用于 [`default`](/guide/reporters#default)、[`verbose`](/guide/reporters#verbose) 或 [`tree`](/guide/reporters#tree) 报告器。 -- Self: the time it took to import the module, excluding static imports; -- Total: the time it took to import the module, including static imports. Note that this does not include `transform` time of the current module. +- Self:导入模块所花费的时间,不包括静态导入; +- Total:导入模块所花费的时间,包括静态导入。请注意,这不包括当前模块的 `transform` 时间。 -An example of import breakdown in the terminal +终端中导入分解的示例 -Note that if the file path is too long, Vitest will truncate it at the start until it fits 45 character limit. +请注意,如果文件路径太长,Vitest 会从开头截断它,直到它符合 45 个字符的限制。 ::: info -[Vitest UI](/guide/ui#import-breakdown) shows a breakdown of imports automatically if at least one file took longer than 500 milliseconds to load. You can manually set this option to `false` to disable this. +如果至少有一个文件加载时间超过 500 毫秒,[Vitest UI](/guide/ui#import-breakdown) 会自动显示导入分解。你可以手动将此选项设置为 `false` 来禁用此功能。 ::: diff --git a/config/index.md b/config/index.md index a2031f25..6b6dbd14 100644 --- a/config/index.md +++ b/config/index.md @@ -12,8 +12,7 @@ outline: deep 要配置 Vitest 本身,请在我们的 Vite 配置中添加 `test` 属性。如果我们是从 `vite` 本身导入 `defineConfig`,我们还需要在配置文件顶部使用 [三斜杠指令](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-) 添加对 Vitest 类型引用。 - -If you are not using `vite`, add `defineConfig` imported from `vitest/config` to your config file: +如果你没有使用 `vite`,可以在配置文件中从 `vitest/config` 导入 `defineConfig`: ```js [vitest.config.js] import { defineConfig } from 'vitest/config' @@ -24,8 +23,8 @@ export default defineConfig({ }, }) ``` - -If you have a `vite` config already, you can add `/// ` to include the `test` types: + +如果你已经有一个 `vite` 配置文件,可以添加 `/// ` 来引入 `test` 类型: ```js [vite.config.js] /// @@ -38,7 +37,7 @@ export default defineConfig({ }) ``` -You can retrieve Vitest's default options to expand them if needed: +如果需要,你可以获取 Vitest 的默认选项来扩展它们: ```js [vitest.config.js] import { configDefaults, defineConfig } from 'vitest/config' @@ -81,5 +80,4 @@ export default defineConfig(configEnv => mergeConfig( 由于 Vitest 使用 Vite 的配置,我们也可以使用 [Vite](https://vitejs.dev/config/) 中的任何配置选项。例如,使用 `define` 来定义全局变量,或者使用 `resolve.alias` 来定义别名——这些选项应该在顶级定义,而不是在 `test` 属性内部。 - -Configuration options that are not supported inside a [project](/guide/projects) config have icon next to them. This means they can only be set in the root Vitest config. +在 [项目](/guide/projects) 配置中不支持的配置选项旁边会有 图标。这意味着它们只能在根 Vitest 配置中设置。 diff --git a/config/onstacktrace.md b/config/onstacktrace.md index 4de50c67..16337288 100644 --- a/config/onstacktrace.md +++ b/config/onstacktrace.md @@ -2,17 +2,17 @@ title: onStackTrace | Config outline: deep --- - + # onStackTrace -- **Type**: `(error: Error, frame: ParsedStack) => boolean | void` +- **类型**: `(error: Error, frame: ParsedStack) => boolean | void` -Apply a filtering function to each frame of each stack trace when handling errors. This does not apply to stack traces printed by [`printConsoleTrace`](/config/printconsoletrace#printconsoletrace). The first argument, `error`, is a `TestError`. +在处理错误时,对每个堆栈跟踪的每一帧应用过滤函数。这不适用于 [`printConsoleTrace`](/config/printconsoletrace#printconsoletrace) 打印的堆栈跟踪。第一个参数 `error` 是一个 `TestError`。 -Can be useful for filtering out stack trace frames from third-party libraries. +可用于过滤掉来自第三方库的堆栈跟踪帧。 ::: tip -The stack trace's total size is also typically limited by V8's [`Error.stackTraceLimit`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stackTraceLimit) number. You could set this to a high value in your test setup function to prevent stacks from being truncated. +堆栈跟踪的总大小通常也受到 V8 的 [`Error.stackTraceLimit`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stackTraceLimit) 数字的限制。你可以在测试设置函数中将其设置为较高的值,以防止堆栈被截断。 ::: ```ts @@ -22,12 +22,12 @@ import { defineConfig } from 'vitest/config' export default defineConfig({ test: { onStackTrace(error: TestError, { file }: ParsedStack): boolean | void { - // If we've encountered a ReferenceError, show the whole stack. + // 如果我们遇到 ReferenceError,显示整个堆栈。 if (error.name === 'ReferenceError') { return } - // Reject all frames from third party libraries. + // 拒绝所有来自第三方库的帧。 if (file.includes('node_modules')) { return false } diff --git a/config/resolvesnapshotpath.md b/config/resolvesnapshotpath.md index 0e1f1a24..6bb1f5cc 100644 --- a/config/resolvesnapshotpath.md +++ b/config/resolvesnapshotpath.md @@ -2,13 +2,13 @@ title: resolveSnapshotPath | Config outline: deep --- - + # resolveSnapshotPath -- **Type**: `(testPath: string, snapExtension: string, context: { config: SerializedConfig }) => string` -- **Default**: stores snapshot files in `__snapshots__` directory +- **类型**: `(testPath: string, snapExtension: string, context: { config: SerializedConfig }) => string` +- **默认值**: 将快照文件存储在 `__snapshots__` 目录中 -Overrides default snapshot path. For example, to store snapshots next to test files: +覆盖默认的快照路径。例如,将快照存储在测试文件旁边: ```ts import { defineConfig } from 'vitest/config' @@ -20,7 +20,7 @@ export default defineConfig({ }) ``` -You can also use the `context` parameter to access the project's serialized config. This is useful when you have multiple [projects](/guide/projects) and want to store snapshots in different locations based on the project name: +你还可以使用 `context` 参数来访问项目的序列化配置。当你有多个 [项目](/guide/projects) 并希望根据项目名称将快照存储在不同位置时,这很有用: ```ts import { basename, dirname, join } from 'node:path' diff --git a/guide/browser/component-testing.md b/guide/browser/component-testing.md index 2904b900..bfee1989 100644 --- a/guide/browser/component-testing.md +++ b/guide/browser/component-testing.md @@ -257,33 +257,33 @@ test('ShoppingCart manages items correctly', async () => { ``` ### 测试带有数据获取的异步组件 {#testing-async-components-with-data-fetching} - + ```tsx -// Option 1: Recommended - Use MSW (Mock Service Worker) for API mocking +// 选项 1:推荐 - 使用 MSW(Mock Service Worker)进行 API 模拟 import { http, HttpResponse } from 'msw' import { setupWorker } from 'msw/browser' -// Set up MSW worker with API handlers +// 使用 API 处理程序设置 MSW worker const worker = setupWorker( http.get('/api/users/:id', ({ params }) => { - // Describe the happy path + // 描述成功路径 return HttpResponse.json({ id: params.id, name: 'John Doe', email: 'john@example.com' }) }) ) -// Start the worker before all tests +// 在所有测试之前启动 worker beforeAll(() => worker.start()) afterEach(() => worker.resetHandlers()) afterAll(() => worker.stop()) test('UserProfile handles loading, success, and error states', async () => { - // Test success state + // 测试成功状态 const { getByText } = render() - // expect.element auto-retries until elements are found + // expect.element 会自动重试直到找到元素 await expect.element(getByText('John Doe')).toBeInTheDocument() await expect.element(getByText('john@example.com')).toBeInTheDocument() - // Test error state by overriding the handler for this test + // 通过为此测试覆盖处理程序来测试错误状态 worker.use( http.get('/api/users/:id', () => { return HttpResponse.json({ error: 'User not found' }, { status: 404 }) @@ -296,13 +296,13 @@ test('UserProfile handles loading, success, and error states', async () => { ``` ::: tip -See more details on [using MSW in the browser](https://mswjs.io/docs/integrations/browser). +查看更多关于[在浏览器中使用 MSW](https://mswjs.io/docs/integrations/browser) 的详细信息。 ::: -### Testing Component Communication +### 测试组件通信 {#testing-component-communication} ```tsx -// Test parent-child component interaction +// 测试父子组件交互 test('parent and child components communicate correctly', async () => { const mockOnSelectionChange = vi.fn() diff --git a/guide/browser/index.md b/guide/browser/index.md index 8f774a09..e6ac3fb9 100644 --- a/guide/browser/index.md +++ b/guide/browser/index.md @@ -2,10 +2,10 @@ title: Browser Mode | Guide outline: deep --- - -# Browser Mode {#browser-mode} -This page provides information about the browser mode feature in the Vitest API, which allows you to run your tests in the browser natively, providing access to browser globals like window and document. +# 浏览器模式 {#browser-mode} + +本页面提供了关于 Vitest API 中浏览器模式功能的信息,该功能允许你在浏览器中原生运行测试,提供对浏览器全局变量(如 window 和 document)的访问。 ::: tip 如果你需要 `expect` 、`vi` ,或者像测试项目、类型测试等通用 API 的文档,请查看 [“快速起步” 指南](/guide/)。 @@ -34,10 +34,10 @@ bunx vitest init browser ::: ### 手动安装 {#manual-installation} - -You can also install packages manually. Vitest always requires a provider to be defined. You can chose either [`preview`](/config/browser/preview), [`playwright`](/config/browser/playwright) or [`webdriverio`](/config/browser/webdriverio). -If you want to just preview how your tests look, you can use the `preview` provider: +你也可以手动安装包。Vitest 始终需要定义一个提供程序。你可以选择 [`preview`](/config/browser/preview)、[`playwright`](/config/browser/playwright) 或 [`webdriverio`](/config/browser/webdriverio)。 + +如果你只想预览测试的外观,可以使用 `preview` 提供程序: ::: code-group ```bash [npm] @@ -57,9 +57,7 @@ bun add -D vitest @vitest/browser-preview ::: warning 不过,要在 CI 中运行测试,我们需要安装 [`playwright`](https://npmjs.com/package/playwright) 或 [`webdriverio`](https://www.npmjs.com/package/webdriverio) 。我们还建议在本地测试时切换到这两个选项中的一个,而不是使用默认的 `preview` 提供程序,因为它依赖于模拟事件而不是使用 Chrome DevTools 协议。 - - -If you don't already use one of these tools, we recommend starting with Playwright because it supports parallel execution, which makes your tests run faster. +如果你还没有使用这些工具中的任何一个,我们建议从 Playwright 开始,因为它支持并行执行,这使你的测试运行得更快。 ::: tabs key:provider == Playwright @@ -121,8 +119,8 @@ export default defineConfig({ ::: info Vitest 默认分配端口号 `63315` 以避免与开发服务器冲突,允许我们同时并行运行两者。我们可以通过 [`browser.api`](/config/#browser-api) 选项来更改这个端口号。 - -The CLI does not print the Vite server URL automatically. You can press "b" to print the URL when running in watch mode. + +CLI 不会自动打印 Vite 服务器 URL。在观察模式下运行时,你可以按 "b" 键来打印 URL。 ::: 如果之前未使用过 Vite,请确保已安装框架插件并在配置中指定。有些框架可能需要额外配置才能运行,请查看其 Vite 相关文档以确定。 diff --git a/guide/browser/visual-regression-testing.md b/guide/browser/visual-regression-testing.md index 0d0c2b19..7138a4b4 100644 --- a/guide/browser/visual-regression-testing.md +++ b/guide/browser/visual-regression-testing.md @@ -101,31 +101,30 @@ $ vitest --update 提交前务必核对更新后的截图,确保改动符合预期。 - -## How Visual Tests Work +## 可视化测试的工作原理 {#how-visual-tests-work} -Visual regression tests need stable screenshots to compare against. But pages aren't instantly stable as images load, animations finish, fonts render, and layouts settle. +可视化回归测试需要稳定的截图进行比较。但页面不会立即稳定,因为图像需要加载、动画需要完成、字体需要渲染、布局需要稳定。 -Vitest handles this automatically through "Stable Screenshot Detection": +Vitest 通过"稳定截图检测"自动处理这一问题: -1. Vitest takes a first screenshot (or uses the reference screenshot if available) as baseline -1. It takes another screenshot and compares it with the baseline - - If the screenshots match, the page is stable and testing continues - - If they differ, Vitest uses the newest screenshot as the baseline and repeats -1. This continues until stability is achieved or the timeout is reached +1. Vitest 拍摄第一张截图(或使用参考截图,如果可用)作为基线 +1. 它拍摄另一张截图并与基线进行比较 + - 如果截图匹配,页面是稳定的,测试继续 + - 如果它们不同,Vitest 使用最新的截图作为基线并重复 +1. 这会持续进行,直到达到稳定性或超时 -This ensures that transient visual changes (like loading spinners or animations) don't cause false failures. If something never stops animating though, you'll hit the timeout, so consider [disabling animations during testing](#disable-animations). +这确保了瞬态视觉变化(如加载旋转器或动画)不会导致错误的失败。但是,如果某些内容永远不会停止动画,你将达到超时,因此请考虑[在测试期间禁用动画](#disable-animations)。 -If a stable screenshot is captured after retries (one or more) and a reference screenshot exists, Vitest performs a final comparison with the reference using `createDiff: true`. This will generate a diff image if they don't match. +如果在重试后(一次或多次)捕获到稳定的截图并且存在参考截图,Vitest 会使用 `createDiff: true` 与参考进行最终比较。如果它们不匹配,这将生成差异图像。 -During stability detection, Vitest calls comparators with `createDiff: false` since it only needs to know if screenshots match. This keeps the detection process fast. +在稳定性检测期间,Vitest 使用 `createDiff: false` 调用比较器,因为它只需要知道截图是否匹配。这使检测过程保持快速。 ## 配置可视化测试 {#configuring-visual-tests} ### 全局配置 {#global-configuration} 可在 [Vitest 配置文件](/config/browser/expect#tomatchscreenshot) 中设定可视化回归测试的默认规则: - + ```ts [vitest.config.ts] import { defineConfig } from 'vitest/config' @@ -136,9 +135,9 @@ export default defineConfig({ toMatchScreenshot: { comparatorName: 'pixelmatch', comparatorOptions: { - // 0-1, how different can colors be? + // 0-1,颜色可以有多大差异? threshold: 0.2, - // 1% of pixels can differ + // 1% 的像素可以不同 allowedMismatchedPixelRatio: 0.01, }, }, @@ -151,12 +150,12 @@ export default defineConfig({ ### 单测试配置 {#per-test-configuration} 若某个测试需要不同的比较标准,可在调用时覆盖全局设置: - + ```ts await expect(element).toMatchScreenshot('button-hover', { comparatorName: 'pixelmatch', comparatorOptions: { - // more lax comparison for text-heavy elements + // 对文本密集型元素进行更宽松的比较 allowedMismatchedPixelRatio: 0.1, }, }) @@ -167,12 +166,12 @@ await expect(element).toMatchScreenshot('button-hover', { ### 聚焦测试目标元素 {#test-specific-elements} 除非确实需要测试整个页面,否则应优先只对目标组件截图,这能显著减少因页面其他部分变化而造成的误报。 - + ```ts -// ❌ Captures entire page; prone to unrelated changes +// ❌ 捕获整个页面;容易受到无关更改的影响 await expect(page).toMatchScreenshot() -// ✅ Captures only the component under test +// ✅ 仅捕获被测试的组件 await expect(page.getByTestId('product-card')).toMatchScreenshot() ``` @@ -633,18 +632,18 @@ export default defineConfig({ ``` 该服务会提供两个关键环境变量: - + - `PLAYWRIGHT_SERVICE_URL`:指示 Playwright 连接的服务器地址 - `PLAYWRIGHT_SERVICE_ACCESS_TOKEN`:你的身份验证令牌 -Follow the [official guide to create a Playwright Workspace](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/quickstart-run-end-to-end-tests?tabs=playwrightcli&pivots=playwright-test-runner#create-a-workspace). +按照[官方指南创建 Playwright 工作区](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/quickstart-run-end-to-end-tests?tabs=playwrightcli&pivots=playwright-test-runner#create-a-workspace)。 -Once your workspace is created, configure Vitest to use it: +创建工作区后,配置 Vitest 以使用它: -1. **Set the endpoint URL**: following the [official guide](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/quickstart-run-end-to-end-tests?tabs=playwrightcli&pivots=playwright-test-runner#configure-the-browser-endpoint), retrieve the URL and set it as the `PLAYWRIGHT_SERVICE_URL` environment variable. -2. **Enable token authentication**: [enable access tokens](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/how-to-manage-authentication?pivots=playwright-test-runner#enable-authentication-using-access-tokens) for your workspace, then [generate a token](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/how-to-manage-access-tokens#generate-a-workspace-access-token) and set it as the `PLAYWRIGHT_SERVICE_ACCESS_TOKEN` environment variable. +1. **设置端点 URL**:按照[官方指南](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/quickstart-run-end-to-end-tests?tabs=playwrightcli&pivots=playwright-test-runner#configure-the-browser-endpoint),检索 URL 并将其设置为 `PLAYWRIGHT_SERVICE_URL` 环境变量。 +2. **启用令牌身份验证**:为你的工作区[启用访问令牌](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/how-to-manage-authentication?pivots=playwright-test-runner#enable-authentication-using-access-tokens),然后[生成令牌](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/how-to-manage-access-tokens#generate-a-workspace-access-token)并将其设置为 `PLAYWRIGHT_SERVICE_ACCESS_TOKEN` 环境变量。 ::: danger 令牌务必保密! 切勿将 `PLAYWRIGHT_SERVICE_ACCESS_TOKEN` 提交到代码仓库。 diff --git a/guide/comparisons.md b/guide/comparisons.md index b25ec4c2..b449091a 100644 --- a/guide/comparisons.md +++ b/guide/comparisons.md @@ -53,32 +53,32 @@ uvu 使用 require 和 loader 钩子 进行代码转译,而 Vitest 使用 [Vit uvu 不提供观察模式以在文件更改后重新运行测试, 而 Vitest 通过 Vite 的模块热重载(HMR)观察模式提供了更好的开发体验。 uvu 是运行简单测试的快速选项, 但对于更复杂的测试和项目, Vitest 可能更快、更可靠。 - + ## Mocha -[Mocha](https://mochajs.org) is a test framework running on Node.js and in the browser. Mocha is a popular choice for server-side testing. Mocha is highly configurable and does not include certain features by default. For example, it does not come with an assertion library, with the idea being that Node's built-in assertion runner is good enough for most use cases. Another popular choice for assertions with Mocha is [Chai](https://www.chaijs.com). +[Mocha](https://mochajs.org) 是一个在 Node.js 和浏览器中运行的测试框架。Mocha 是服务器端测试的热门选择。Mocha 高度可配置,默认情况下不包含某些功能。例如,它不自带断言库,其理念是 Node 的内置断言运行器对大多数用例来说已经足够好了。在 Mocha 中,另一个流行的断言库选择是 [Chai](https://www.chaijs.com)。 -Vitest also provides out-of-the-box setup for a few other features, which take additional configuration or the addition of other libraries in Mocha, for example: +Vitest 还为一些其他功能提供了开箱即用的设置,而这些功能在 Mocha 中需要额外的配置或添加其他库,例如: -- Snapshot testing +- 快照测试 - TypeScript -- JSX support -- Code Coverage -- Mocking -- Smart watch mode (only re-runs affected tests) +- JSX 支持 +- 代码覆盖率 +- 模拟对象(Mocking) +- 智能观察模式(仅重新运行受影响的测试) -While Mocha supports Native ESM, it has limitations and configuration constraints. Watch mode does not work with ES Module files, for example. +虽然 Mocha 支持原生 ESM,但它有一些限制和配置约束。例如,观察模式不能与 ES 模块文件一起使用。 -Performance-wise, Mocha runs tests serially by default but supports parallel execution with the `--parallel` flag (though some reporters and features don't work in parallel mode). +在性能方面,Mocha 默认串行运行测试,但支持使用 `--parallel` 标志进行并行执行(尽管某些报告器和功能在并行模式下不起作用)。 -If you're already using Vite in your build pipeline, Vitest allows you to reuse the same configuration and plugins for testing, whereas Mocha would require a separate test setup. Vitest provides a Jest-compatible API while also supporting Mocha's familiar `describe`, `it`, and hook syntax, making migration straightforward for most test suites. +如果你已经在构建管道中使用 Vite,Vitest 允许你重用相同的配置和插件进行测试,而 Mocha 则需要单独的测试设置。Vitest 提供了与 Jest 兼容的 API,同时也支持 Mocha 熟悉的 `describe`、`it` 和钩子语法,使大多数测试套件的迁移变得简单直接。 -Mocha remains a solid choice for projects that need a minimal, flexible test runner with complete control over their testing stack. However, if you want a modern testing experience with everything included out of the box - especially for Vite-powered applications - Vitest has you covered. +Mocha 对于需要最小化、灵活的测试运行器并完全控制其测试堆栈的项目来说,仍然是一个可靠的选择。然而,如果你想要一个开箱即用的现代测试体验——特别是对于 Vite 驱动的应用程序——Vitest 可以满足你的需求。 ## Playwright -[Playwright](https://playwright.dev) is a testing framework from Microsoft that excels at end-to-end testing across multiple browsers (Chromium, Firefox, and WebKit). It controls real browsers to test complete user workflows—from logging in and navigating your app to submitting forms and verifying results. Vitest, on the other hand, is optimised for fast, isolated unit and component tests in a headless environment. These differences make it an ideal complement to Vitest. +[Playwright](https://playwright.dev) 是微软推出的一个测试框架,擅长跨多个浏览器(Chromium、Firefox 和 WebKit)进行端到端测试。它控制真实的浏览器来测试完整的用户工作流程——从登录和导航应用程序到提交表单和验证结果。另一方面,Vitest 针对无头环境中的快速、隔离的单元测试和组件测试进行了优化。这些差异使它成为 Vitest 的理想补充。 -A standard setup is to use Vitest for all unit and component tests (business logic, utilities, hooks, and UI component tests), and Playwright for end-to-end tests that verify critical user paths and cross-browser compatibility. This combination gives you fast feedback during development with Vitest while ensuring your complete application works correctly in real browsers with Playwright. +标准的设置是将 Vitest 用于所有单元测试和组件测试(业务逻辑、工具函数、钩子和 UI 组件测试),将 Playwright 用于验证关键用户路径和跨浏览器兼容性的端到端测试。这种组合让你在开发过程中通过 Vitest 获得快速反馈,同时通过 Playwright 确保完整的应用程序在真实浏览器中正常工作。 -Vitest recently introduced [browser mode](https://vitest.dev/api/browser), which runs tests in real browsers. However, there are key architectural differences: Playwright component tests run in a Node.js process and control the browser remotely. Vitest's browser mode runs tests natively in the browser, maintaining consistency with Vitest's test runner and developer experience, but it does have some [limitations](/guide/browser/#limitations). +Vitest 最近引入了[浏览器模式](https://vitest.dev/api/browser),可以在真实浏览器中运行测试。然而,存在关键的架构差异:Playwright 组件测试在 Node.js 进程中运行并远程控制浏览器。Vitest 的浏览器模式在浏览器中原生运行测试,与 Vitest 的测试运行器和开发者体验保持一致,但它确实有一些[限制](/guide/browser/#limitations)。 diff --git a/guide/features.md b/guide/features.md index e11f4c09..eb878597 100644 --- a/guide/features.md +++ b/guide/features.md @@ -39,9 +39,8 @@ $ vitest ## 多线程 {#threads} - -By default Vitest runs test files in [multiple processes](/guide/parallelism) using [`node:child_process`](https://nodejs.org/api/child_process.html), allowing tests to run simultaneously. If you want to speed up your test suite even further, consider enabling `--pool=threads` to run tests using [`node:worker_threads`](https://nodejs.org/api/worker_threads.html) (beware that some packages might not work with this setup). -To run tests in a single thread or process, see [`fileParallelism`](/config/#fileParallelism). +默认情况下,Vitest 使用 [`node:child_process`](https://nodejs.org/api/child_process.html) 在[多个进程](/guide/parallelism)中运行测试文件,允许测试同时运行。如果你想进一步加快测试套件的速度,可以考虑启用 `--pool=threads` 来使用 [`node:worker_threads`](https://nodejs.org/api/worker_threads.html) 运行测试(请注意,某些包可能无法在此设置下工作)。 +要在单个线程或进程中运行测试,请参阅 [`fileParallelism`](/config/#fileParallelism)。 Vitest 还隔离了每个测试文件的运行环境,因此一个文件中的运行环境改变不会影响其他文件。可以通过将 `--no-isolate` 传递给 CLI 来禁用隔离(以正确性换取运行性能)。 diff --git a/guide/migration.md b/guide/migration.md index cd73cd96..b32f6c8c 100644 --- a/guide/migration.md +++ b/guide/migration.md @@ -64,16 +64,15 @@ export default defineConfig({ - [覆盖率报告中的文件包含与排除](/guide/coverage.html#including-and-excluding-files-from-coverage-report) - [性能分析 | 代码覆盖率](/guide/profiling-test-performance.html#code-coverage) 了解调试覆盖率生成的方法 - -### Simplified `exclude` +### 简化的 `exclude` 配置 {#simplified-exclude} -By default, Vitest now only excludes tests from `node_modules` and `.git` folders. This means that Vitest no longer excludes: +默认情况下,Vitest 现在只从 `node_modules` 和 `.git` 文件夹中排除测试。这意味着 Vitest 不再排除: -- `dist` and `cypress` folders -- `.idea`, `.cache`, `.output`, `.temp` folders -- config files like `rollup.config.js`, `prettier.config.js`, `ava.config.js` and so on +- `dist` 和 `cypress` 文件夹 +- `.idea`、`.cache`、`.output`、`.temp` 文件夹 +- 配置文件,如 `rollup.config.js`、`prettier.config.js`、`ava.config.js` 等 -If you need to limit the directory where your tests files are located, use the [`test.dir`](/config/dir) option instead because it is more performant than excluding files: +如果你需要限制测试文件所在的目录,请使用 [`test.dir`](/config/dir) 选项,因为它比排除文件更高效: ```ts import { configDefaults, defineConfig } from 'vitest/config' @@ -85,7 +84,7 @@ export default defineConfig({ }) ``` -To restore the previous behaviour, specify old `excludes` manually: +要恢复之前的行为,请手动指定旧的 `excludes`: ```ts import { configDefaults, defineConfig } from 'vitest/config' diff --git a/guide/mocking/modules.md b/guide/mocking/modules.md index c0748f37..47bf0566 100644 --- a/guide/mocking/modules.md +++ b/guide/mocking/modules.md @@ -2,8 +2,7 @@ ## 模块的定义 {#defining-a-module} - -Before mocking a "module", we should define what it is. In Vitest context, the "module" is a file that exports something. Using [plugins](https://vite.dev/guide/api-plugin.html), any file can be turned into a JavaScript module. The "module object" is a namespace object that holds dynamic references to exported identifiers. Simply put, it's an object with exported methods and properties. In this example, `example.js` is a module that exports `answer` and `variable`: +在模拟“模块”之前,我们应该定义它是什么。在 Vitest 上下文中,“模块”是导出某些内容的文件。使用 [插件](https://vite.dev/guide/api-plugin.html),任何文件都可以转换为 JavaScript 模块。"模块对象"是一个命名空间对象,它保存对导出标识符的动态引用。简单来说,它是一个具有导出方法和属性的对象。在此示例中,`example.js` 是一个导出 `answer` 和 `variable` 的模块: ```js [example.js] export function answer() { @@ -40,13 +39,12 @@ import { answer, variable } from './example.js' 要完全替换一个模块,可以使用 [`vi.mock` API](/api/vi#vi-mock)。 在调用 `vi.mock` 时,通过传入一个工厂函数作为第二个参数,该函数返回的新模块将动态替代原模块。 - ```ts import { vi } from 'vitest' -// The ./example.js module will be replaced with -// the result of a factory function, and the -// original ./example.js module will never be called +// ./example.js 模块将被替换为 +// 工厂函数的结果,并且 +// 原始的 ./example.js 模块将永远不会被调用 vi.mock(import('./example.js'), () => { return { answer() { @@ -336,8 +334,8 @@ vi.mock('./answer.js') const __vitest_module_0__ = await __handle_mock__( () => import('./answer.js') ) -// to keep the live binding, we have to access -// the export on the module namespace +// 为了保持实时绑定,我们必须通过 +// 模块命名空间来访问导出 console.log(__vitest_module_0__.answer()) ``` ::: @@ -437,12 +435,12 @@ export function foobar() { import { vi } from 'vitest' import * as mod from './foobar.js' -// this will only affect "foo" outside of the original module +// 这只会影响原始模块外部的 "foo" vi.spyOn(mod, 'foo') vi.mock(import('./foobar.js'), async (importOriginal) => { return { ...await importOriginal(), - // this will only affect "foo" outside of the original module + // 这只会影响原始模块外部的 "foo" foo: () => 'mocked' } }) @@ -455,7 +453,7 @@ import * as mod from './foobar.js' vi.spyOn(mod, 'foo') -// exported foo references mocked method +// 导出的 foo 引用的是被 mock 的方法 mod.foobar(mod.foo) ``` diff --git a/guide/open-telemetry.md b/guide/open-telemetry.md index 05f4ba2b..2f6c4e53 100644 --- a/guide/open-telemetry.md +++ b/guide/open-telemetry.md @@ -1,5 +1,5 @@ -# Open Telemetry Support {#open-telemetry-support} - +# Open Telemetry 支持 {#open-telemetry-support} + ::: tip 功能反馈 请将关于此功能反馈提交至 [GitHub Discussion](https://github.com/vitest-dev/vitest/discussions/9222)。 ::: @@ -8,21 +8,21 @@ [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/opentelemetry) ::: -[OpenTelemetry](https://opentelemetry.io/) traces can be a useful tool to debug the performance and behavior of your application inside tests. +[OpenTelemetry](https://opentelemetry.io/) 追踪可以成为调试测试中应用程序性能和行为的有用工具。 -If enabled, Vitest integration generates spans that are scoped to your test's worker. +如果启用,Vitest 集成会生成作用域限定在测试工作者的跨度(spans)。 ::: warning -OpenTelemetry initialization increases the startup time of every test unless Vitest runs without [isolation](/config/isolate). You can see it as the `vitest.runtime.traces` span inside `vitest.worker.start`. +OpenTelemetry 初始化会增加每个测试的启动时间,除非 Vitest 在没有 [隔离](/config/isolate) 的情况下运行。你可以在 `vitest.worker.start` 内部看到它作为 `vitest.runtime.traces` 跨度。 ::: -To start using OpenTelemetry in Vitest, specify an SDK module path via [`experimental.openTelemetry.sdkPath`](/config/experimental#experimental-opentelemetry) and set `experimental.openTelemetry.enabled` to `true`. Vitest will automatically instrument the whole process and each individual test worker. +要在 Vitest 中开始使用 OpenTelemetry,请通过 [`experimental.openTelemetry.sdkPath`](/config/experimental#experimental-opentelemetry) 指定 SDK 模块路径,并将 `experimental.openTelemetry.enabled` 设置为 `true`。Vitest 将自动检测整个进程和每个单独的测试工作者。 -Make sure to export the SDK as a default export, so that Vitest can flush the network requests before the process is closed. Note that Vitest doesn't automatically call `start`. +确保将 SDK 作为默认导出导出,以便 Vitest 可以在进程关闭之前刷新网络请求。请注意,Vitest 不会自动调用 `start`。 -## Quickstart +## 快速开始 {#quickstart} -Before previewing your application traces, install required packages and specify the path to your instrumentation file in the config. +在预览应用程序追踪之前,请安装所需的包并在配置中指定检测文件的路径。 ```shell npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-proto @@ -59,17 +59,17 @@ export default defineConfig({ ``` ::: -::: danger FAKE TIMERS -If you are using fake timers, it is important to reset them before the test ends, otherwise traces might not be tracked properly. +::: danger 假计时器 +如果你正在使用假计时器(fake timers),在测试结束前重置它们很重要,否则追踪可能无法正确跟踪。 ::: -Vitest doesn't process the `sdkPath` module, so it is important that the SDK can be imported within your Node.js environment. It is ideal to use the `.js` extension for this file. Using another extension will slow down your tests and may require providing additional Node.js arguments. +Vitest 不会处理 `sdkPath` 模块,因此 SDK 能够在你的 Node.js 环境中导入很重要。理想情况下,为此文件使用 `.js` 扩展名。使用其他扩展名会减慢测试速度,并可能需要提供额外的 Node.js 参数。 -If you want to provide a TypeScript file, make sure to familiarize yourself with [TypeScript](https://nodejs.org/api/typescript.html#type-stripping) page in the Node.js documentation. +如果你想提供 TypeScript 文件,请确保熟悉 Node.js 文档中的 [TypeScript](https://nodejs.org/api/typescript.html#type-stripping) 页面。 -## Custom Traces +## 自定义追踪 {#custom-traces} -You can use the OpenTelemetry API yourself to track certain operations in your code. Custom traces automatically inherit the Vitest OpenTelemetry context: +你可以自己使用 OpenTelemetry API 来跟踪代码中的某些操作。自定义追踪会自动继承 Vitest OpenTelemetry 上下文: ```ts import { trace } from '@opentelemetry/api' @@ -79,16 +79,16 @@ import { db } from './src/db' const tracer = trace.getTracer('vitest') test('db connects properly', async () => { - // this is shown inside `vitest.test.runner.test.callback` span + // 这会显示在 `vitest.test.runner.test.callback` 跨度内部 await tracer.startActiveSpan('db.connect', () => db.connect()) }) ``` -## Browser Mode +## 浏览器模式 {#browser-mode} -When running tests in [browser mode](/guide/browser/), Vitest propagates trace context between Node.js and the browser. Node.js side traces (test orchestration, browser driver communication) are available without additional configuration. +在[浏览器模式](/guide/browser/)下运行测试时,Vitest 会在 Node.js 和浏览器之间传播追踪上下文。Node.js 端的追踪(测试编排、浏览器驱动程序通信)无需额外配置即可使用。 -To capture traces from the browser runtime, provide a browser-compatible SDK via `browserSdkPath`: +要从浏览器运行时捕获追踪,请通过 `browserSdkPath` 提供与浏览器兼容的 SDK: ```shell npm i @opentelemetry/sdk-trace-web @opentelemetry/exporter-trace-otlp-proto @@ -133,24 +133,24 @@ export default defineConfig({ ``` ::: -::: warning ASYNC CONTEXT -Unlike Node.js, browsers do not have automatic async context propagation. Vitest handles this internally for test execution, but custom spans in deeply nested async code may not propagate context automatically. +::: warning 异步上下文 +与 Node.js 不同,浏览器没有自动的异步上下文传播。Vitest 在内部为测试执行处理这一点,但深度嵌套异步代码中的自定义跨度可能不会自动传播上下文。 ::: -## View Traces +## 查看追踪 {#view-traces} -To generate traces, run Vitest as usual. You can run Vitest in either watch mode or run mode. Vitest will call `sdk.shutdown()` manually after everything is finished to make sure traces are handled properly. +要生成追踪,请像往常一样运行 Vitest。你可以在观察模式或运行模式下运行 Vitest。Vitest 会在一切完成后手动调用 `sdk.shutdown()`,以确保追踪得到正确处理。 -You can view traces using any of the open source or commercial products that support OpenTelemetry API. If you did not use OpenTelemetry before, we recommend starting with [Jaeger](https://www.jaegertracing.io/docs/2.11/getting-started/#all-in-one) because it is really easy to setup. +你可以使用任何支持 OpenTelemetry API 的开源或商业产品来查看追踪。如果你之前没有使用过 OpenTelemetry,我们建议从 [Jaeger](https://www.jaegertracing.io/docs/2.11/getting-started/#all-in-one) 开始,因为它真的很容易设置。 -## `@opentelemetry/api` +## `@opentelemetry/api` {#opentelemetry-api} -Vitest declares `@opentelemetry/api` as an optional peer dependency, which it uses internally to generate spans. When trace collection is not enabled, Vitest will not attempt to use this dependency. +Vitest 将 `@opentelemetry/api` 声明为可选的对等依赖项,它在内部使用它来生成跨度。当未启用追踪收集时,Vitest 不会尝试使用此依赖项。 -When configuring Vitest to use OpenTelemetry, you will typically install `@opentelemetry/sdk-node`, which includes `@opentelemetry/api` as a transitive dependency, thereby satisfying Vitest's peer dependency requirement. If you encounter an error indicating that `@opentelemetry/api` cannot be found, this typically means trace collection has not been enabled. If the error persists after proper configuration, you may need to install `@opentelemetry/api` explicitly. +在配置 Vitest 使用 OpenTelemetry 时,你通常会安装 `@opentelemetry/sdk-node`,它包含 `@opentelemetry/api` 作为传递依赖项,从而满足 Vitest 的对等依赖项要求。如果你遇到指示找不到 `@opentelemetry/api` 的错误,这通常意味着未启用追踪收集。如果在正确配置后错误仍然存在,你可能需要显式安装 `@opentelemetry/api`。 -## Inter-Process Context Propagation +## 进程间上下文传播 {#inter-process-context-propagation} -Vitest supports automatic context propagation from parent processes via the `TRACEPARENT` and `TRACESTATE` environment variables as defined in the [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/env-carriers.md). This is particularly useful when running Vitest as part of a larger distributed tracing system (e.g., CI/CD pipelines with OpenTelemetry instrumentation). +Vitest 支持通过 `TRACEPARENT` 和 `TRACESTATE` 环境变量从父进程自动传播上下文,如 [OpenTelemetry 规范](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/env-carriers.md)中所定义。这在将 Vitest 作为更大的分布式追踪系统的一部分运行时特别有用(例如,具有 OpenTelemetry 检测的 CI/CD 管道)。 diff --git a/guide/parallelism.md b/guide/parallelism.md index f46ed7c5..c0a515ba 100644 --- a/guide/parallelism.md +++ b/guide/parallelism.md @@ -12,8 +12,7 @@ outline: deep - `forks`(默认)和 `vmForks` 会在不同的 [child processes](https://nodejs.org/api/child_process.html) 中执行测试 - `threads` 和 `vmThreads` 则会在不同的 [worker threads](https://nodejs.org/api/worker_threads.html) 中运行 - -Both "child processes" and "worker threads" are refered to as "workers". You can configure the number of running workers with [`maxWorkers`](/config/#maxworkers) option. +"子进程(child processes)"和"工作线程(worker threads)"统称为"工作者(workers)"。你可以通过 [`maxWorkers`](/config/#maxworkers) 选项来配置运行的工作者数量。 如果项目包含大量测试文件,通常并行执行会大幅提升速度。但具体效果还要看项目本身、运行环境以及是否启用了 [隔离](/config/#isolate)。若需要关闭文件级并行化,可以将 [`fileParallelism`](/config/#fileparallelism) 设为 `false` 。更多性能优化技巧,请参考 [性能指南](/guide/improving-performance) 。 diff --git a/guide/profiling-test-performance.md b/guide/profiling-test-performance.md index cd046da3..ba2684a5 100644 --- a/guide/profiling-test-performance.md +++ b/guide/profiling-test-performance.md @@ -14,12 +14,12 @@ > Duration 4.80s (transform 44ms, setup 0ms, import 35ms, tests 4.52s, environment 0ms) > # Time metrics ^^ > ``` - -- Transform: How much time was spent transforming the files. See [File Transform](#file-transform). -- Setup: Time spent for running the [`setupFiles`](/config/#setupfiles) files. -- Import: Time it took to import your test files and their dependencies. This also includes the time spent collecting all tests. Note that this doesn't include dynamic imports inside of tests. -- Tests: Time spent for actually running the test cases. -- Environment: Time spent for setting up the test [`environment`](/config/#environment), for example JSDOM. + +- Transform:转换文件所花费的时间。参见 [文件转换](#file-transform)。 +- Setup:运行 [`setupFiles`](/config/#setupfiles) 文件所花费的时间。 +- Import:导入测试文件及其依赖项所花费的时间。这也包括收集所有测试所花费的时间。注意,这不包括测试内部的动态导入。 +- Tests:实际运行测试用例所花费的时间。 +- Environment:设置测试 [`environment`](/config/#environment) 所花费的时间,例如 JSDOM。 ## 测试运行器 {#test-runner} @@ -33,8 +33,7 @@ 由于 `node:worker_threads` 的限制, `--prof` 不能与 `pool: 'threads'` 一起使用。 ::: - -To pass these options to Vitest's test runner, define `execArgv` in your Vitest configuration: +要将这些选项传递给 Vitest 的测试运行器,请在 Vitest 配置中定义 `execArgv`: ```ts import { defineConfig } from 'vitest/config' diff --git a/guide/test-context.md b/guide/test-context.md index 2cd7e219..d680e916 100644 --- a/guide/test-context.md +++ b/guide/test-context.md @@ -405,17 +405,16 @@ const test = baseTest.extend({ ], }) ``` - ::: warning -The built-in [`task`](#task) test context is **not available** in file-scoped or worker-scoped fixtures. These fixtures receive a different context object (file or worker context) that does not include test-specific properties like `task`. +内置的 [`task`](#task) 测试上下文在文件作用域或工作者作用域的 fixtures 中**不可用**。这些 fixtures 接收不同的上下文对象(文件或工作者上下文),不包括像 `task` 这样的测试特定属性。 -If you need access to file-level metadata like the file path, use `expect.getState().testPath` instead. +如果你需要访问文件级元数据(如文件路径),请改用 `expect.getState().testPath`。 ::: `worker` 作用域将为每个工作线程运行一次夹具。运行的工作线程数量取决于各种因素。默认情况下,每个文件在单独的工作线程中运行,因此 `file` 和 `worker` 作用域的工作方式相同。 -However, if you disable [isolation](/config/#isolate), then the number of workers is limited by the [`maxWorkers`](/config/#maxworkers) configuration. +但是,如果你禁用 [隔离](/config/#isolate),那么工作者的数量将受到 [`maxWorkers`](/config/#maxworkers) 配置的限制。 请注意,在 `vmThreads` 或 `vmForks` 中运行测试时,指定 `scope: 'worker'` 的工作方式与 `scope: 'file'` 相同。这个限制存在是因为每个测试文件都有自己的 VM 上下文,所以如果 Vitest 只初始化一次,一个上下文可能会泄漏到另一个上下文中,并创建许多引用不一致的问题(例如,同一个类的实例会引用不同的构造函数)。 From 313eb8094fcf315a3ea71dcc988df74b87c47492 Mon Sep 17 00:00:00 2001 From: WuMingDao <146366930+WuMingDao@users.noreply.github.com> Date: Sun, 4 Jan 2026 16:48:30 +0800 Subject: [PATCH 02/31] fix test-context --- guide/test-context.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/guide/test-context.md b/guide/test-context.md index d680e916..5921a154 100644 --- a/guide/test-context.md +++ b/guide/test-context.md @@ -407,14 +407,14 @@ const test = baseTest.extend({ ``` ::: warning -内置的 [`task`](#task) 测试上下文在文件作用域或工作者作用域的 fixtures 中**不可用**。这些 fixtures 接收不同的上下文对象(文件或工作者上下文),不包括像 `task` 这样的测试特定属性。 +内置的 [`task`](#task) 测试上下文在文件作用域或工作者作用域的 fixtures 中 **不可用**。这些 fixtures 接收不同的上下文对象(文件或工作者上下文),不包括像 `task` 这样的测试特定属性。 如果你需要访问文件级元数据(如文件路径),请改用 `expect.getState().testPath`。 ::: `worker` 作用域将为每个工作线程运行一次夹具。运行的工作线程数量取决于各种因素。默认情况下,每个文件在单独的工作线程中运行,因此 `file` 和 `worker` 作用域的工作方式相同。 -但是,如果你禁用 [隔离](/config/#isolate),那么工作者的数量将受到 [`maxWorkers`](/config/#maxworkers) 配置的限制。 +但是,如果你禁用 [隔离](/config/#isolate),那么工作线程数量将受到 [`maxWorkers`](/config/#maxworkers) 配置的限制。 请注意,在 `vmThreads` 或 `vmForks` 中运行测试时,指定 `scope: 'worker'` 的工作方式与 `scope: 'file'` 相同。这个限制存在是因为每个测试文件都有自己的 VM 上下文,所以如果 Vitest 只初始化一次,一个上下文可能会泄漏到另一个上下文中,并创建许多引用不一致的问题(例如,同一个类的实例会引用不同的构造函数)。 From a2f7bb5c05eee5c6b6114c6b17b087022ae863a8 Mon Sep 17 00:00:00 2001 From: wumingdao Date: Sun, 4 Jan 2026 22:36:22 +0800 Subject: [PATCH 03/31] fix: test-context next --- guide/test-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guide/test-context.md b/guide/test-context.md index 7e33f91a..bf1f8abf 100644 --- a/guide/test-context.md +++ b/guide/test-context.md @@ -94,7 +94,7 @@ function annotate( ): Promise ``` -添加一个[测试注解](/guide/test-annotations),它将由你的[报告器](/config/#reporters)显示。 +添加一个 [测试注解](/guide/test-annotations),它将由你的 [报告器](/config/#reporters) 显示。 ```ts test('annotations API', async ({ annotate }) => { From daa5014626f40cf46315519b59b094d0843dd0b5 Mon Sep 17 00:00:00 2001 From: noise Date: Mon, 5 Jan 2026 12:54:19 +0800 Subject: [PATCH 04/31] docs(cn): update api/advanced/plugin --- .vitepress/components/Experimental.vue | 2 +- api/advanced/plugin.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.vitepress/components/Experimental.vue b/.vitepress/components/Experimental.vue index 18681c68..a528c7cc 100644 --- a/.vitepress/components/Experimental.vue +++ b/.vitepress/components/Experimental.vue @@ -1,5 +1,5 @@ diff --git a/api/advanced/plugin.md b/api/advanced/plugin.md index 37176aba..b023aeb4 100644 --- a/api/advanced/plugin.md +++ b/api/advanced/plugin.md @@ -138,9 +138,9 @@ function experimental_defineCacheKeyGenerator( ): void ``` -定义一个生成器,它将在哈希缓存键之前应用。 +定义一个缓存键生成器,它将在缓存键哈希之前运行。 -使用此方法确保 Vitest 生成正确的哈希。如果你的插件可以使用不同的选项注册,定义此函数是一个好主意。 +通过这种方式,可以确保 Vitest 生成正确的哈希值。如果你的插件支持通过不同的参数选项注册,建议使用此函数。 仅当定义了 [`experimental.fsModuleCache`](/config/experimental#experimental-fsmodulecache) 时才会调用此方法。 @@ -162,7 +162,7 @@ export function plugin(options: PluginOptions) { configureVitest({ experimental_defineCacheKeyGenerator }) { experimental_defineCacheKeyGenerator(() => { // 由于这些选项会影响转换结果, - // 将它们作为唯一字符串一起返回 + // 将它们组合成一个唯一字符串并返回 return options.replacePropertyKey + options.replacePropertyValue }) } From 0e915c6b68647f68269688715f49af08286ea2ce Mon Sep 17 00:00:00 2001 From: noise Date: Mon, 5 Jan 2026 12:56:06 +0800 Subject: [PATCH 05/31] docs(cn): update api/advanced/plugin --- api/advanced/plugin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/advanced/plugin.md b/api/advanced/plugin.md index b023aeb4..3f94f4b7 100644 --- a/api/advanced/plugin.md +++ b/api/advanced/plugin.md @@ -140,7 +140,7 @@ function experimental_defineCacheKeyGenerator( 定义一个缓存键生成器,它将在缓存键哈希之前运行。 -通过这种方式,可以确保 Vitest 生成正确的哈希值。如果你的插件支持通过不同的参数选项注册,建议使用此函数。 +如果你的插件支持通过不同的参数选项注册,建议通过这种方式,确保 Vitest 生成正确的哈希值。 仅当定义了 [`experimental.fsModuleCache`](/config/experimental#experimental-fsmodulecache) 时才会调用此方法。 From 7c5d1d5e882d40c566b1d7d44461e96eb2091d14 Mon Sep 17 00:00:00 2001 From: noise Date: Tue, 6 Jan 2026 00:34:58 +0800 Subject: [PATCH 06/31] docs(cn): update /api/expect-typeof --- api/expect-typeof.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/expect-typeof.md b/api/expect-typeof.md index efe8b7dc..5f255500 100644 --- a/api/expect-typeof.md +++ b/api/expect-typeof.md @@ -557,12 +557,12 @@ expectTypeOf(obj).toHaveProperty('a').not.toBeString() - **类型:** `ExpectTypeOf` -你可以使用 `.branded` 来允许类型断言对语义上等效但表示形式不同的类型成功。 +可以使用 `.branded` 来允许类型断言成功,适用于那些语义上等价但表示形式不同的类型。 ```ts import { expectTypeOf } from 'vitest' -// 没有 .branded,即使类型实际上相同,这也会失败 +// 没有使用 .branded,即使实际上类型相同,但也会断言失败 expectTypeOf<{ a: { b: 1 } & { c: 1 } }>().toEqualTypeOf<{ a: { b: 1; c: 1 } }>() // 使用 .branded,断言成功 @@ -570,5 +570,5 @@ expectTypeOf<{ a: { b: 1 } & { c: 1 } }>().branded.toEqualTypeOf<{ a: { b: 1; c: ``` ::: warning -此辅助函数会带来性能成本,如果用于过深的类型,可能会导致 TypeScript 编译器"放弃"。请谨慎使用,仅在必要时使用。 +此工具函数会带来性能开销,并且在处理过深类型时可能导致 TypeScript 编译器 “崩溃”。请谨慎使用,仅在必要时使用。 ::: From eda04962b3424fb1c183475a887e75941d9fce2e Mon Sep 17 00:00:00 2001 From: noise Date: Tue, 6 Jan 2026 20:58:15 +0800 Subject: [PATCH 07/31] update(cn): update api/browser/interactivity.md --- api/browser/interactivity.md | 15 +++++++-------- api/expect-typeof.md | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/api/browser/interactivity.md b/api/browser/interactivity.md index ab344ef1..d2b79fed 100644 --- a/api/browser/interactivity.md +++ b/api/browser/interactivity.md @@ -61,23 +61,22 @@ test('clicks on an element', async () => { // 或者你可以直接从定位器上访问 await logo.click() - // 使用 WebdriverIO 时,这会使用 ElementClick(无参数时)或 - // actions(有参数时)。使用空对象可以强制使用 actions。 + // 在 WebdriverIO 中,该方法根据参数情况使用 ElementClick(无参数时)或行为链(有参数时) + // 传入空对象可以强制使用行为链 await logo.click({}) }) ``` -### 使用修饰键点击 +### 使用修饰键点击 {#clicking-with-a-modifier} 使用 WebdriverIO 或 Playwright: ```ts await userEvent.keyboard('{Shift>}') -// 通过使用空对象作为选项,这会选择使用一系列操作 -// 而不是 webdriver 中的 ElementClick。 -// Firefox 有一个 bug 使这成为必要。 -// 关注 https://bugzilla.mozilla.org/show_bug.cgi?id=1456642 以了解何时 -// 修复此问题。 +// 通过传入空对象作为选项参数,该方法强制会选择使用行为链 +// 而非 webdriver 的原生 ElementClick +// 由于 Firefox 存在一个 bug ,所以必须使用这种方式 +// 关注 https://bugzilla.mozilla.org/show_bug.cgi?id=1456642 以获取该问题的修复进展 await userEvent.click(element, {}) await userEvent.keyboard('{/Shift}') ``` diff --git a/api/expect-typeof.md b/api/expect-typeof.md index 5f255500..cb923736 100644 --- a/api/expect-typeof.md +++ b/api/expect-typeof.md @@ -557,7 +557,7 @@ expectTypeOf(obj).toHaveProperty('a').not.toBeString() - **类型:** `ExpectTypeOf` -可以使用 `.branded` 来允许类型断言成功,适用于那些语义上等价但表示形式不同的类型。 +你可以使用 `.branded` 来允许那些语义上等价,但表示形式不同的类型断言成功。 ```ts import { expectTypeOf } from 'vitest' @@ -570,5 +570,5 @@ expectTypeOf<{ a: { b: 1 } & { c: 1 } }>().branded.toEqualTypeOf<{ a: { b: 1; c: ``` ::: warning -此工具函数会带来性能开销,并且在处理过深类型时可能导致 TypeScript 编译器 “崩溃”。请谨慎使用,仅在必要时使用。 +此工具函数会带来性能开销,并且在处理过深类型时可能导致 TypeScript 编译器 “崩溃”。仅在必要时谨慎使用。 ::: From 1d3664cfdad9e8186a18053406aac42412be68c9 Mon Sep 17 00:00:00 2001 From: noise Date: Tue, 6 Jan 2026 23:37:56 +0800 Subject: [PATCH 08/31] docs(cn): update api/advanced/vitest --- api/advanced/vitest.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/advanced/vitest.md b/api/advanced/vitest.md index 701092ad..db793ba1 100644 --- a/api/advanced/vitest.md +++ b/api/advanced/vitest.md @@ -464,7 +464,7 @@ function onCancel(fn: (reason: CancelReason) => Awaitable): () => void 注册一个处理程序,当测试运行被 [`vitest.cancelCurrentRun`](#cancelcurrentrun) 取消时调用。 ::: warning 实验性 -自 4.0.10 起,`onCancel` 返回一个清理函数,用于移除监听器。 +自 4.0.10 起,`onCancel` 会返回一个用于移除监听器的清理函数。 ::: ## onClose @@ -612,7 +612,7 @@ function experimental_parseSpecifications( ): Promise ``` -此方法将从规范数组中 [收集测试](#parsespecification)。默认情况下,Vitest 一次只运行 `os.availableParallelism()` 数量的规范,以减少潜在的性能下降。你可以在第二个参数中指定不同的数字。 +此方法将从规范数组中 [收集测试用例](#parsespecification)。默认情况下,Vitest 每次仅会并行运行 `os.availableParallelism()` 数量的规范,以降低潜在的性能损耗。你可以通过第二个参数指定不同的并发数量。 ## experimental_clearCache 4.0.11 {#clearcache} @@ -673,8 +673,8 @@ export interface SourceModuleDiagnostic { ``` ::: -返回模块的诊断信息。如果未提供 [`testModule`](/api/advanced/test-module),`selfTime` 和 `totalTime` 将汇总上次运行的所有测试。如果模块未被转换或执行,诊断信息将为空。 +返回模块的诊断信息。如果未提供 [`testModule`](/api/advanced/test-module),则 `selfTime` 和 `totalTime` 将聚合上次运行的所有测试。如果模块未被转换或执行,诊断信息将为空。 ::: warning -目前不支持 [浏览器](/guide/browser/) 模块。 +[浏览器模式](/guide/browser/) 暂不支持。 ::: From d5dc8f5c1a4dc99d043361570ac3f4c0a6104816 Mon Sep 17 00:00:00 2001 From: noise Date: Wed, 7 Jan 2026 13:00:17 +0800 Subject: [PATCH 09/31] docs(cn): update /api/index --- api/index.md | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/api/index.md b/api/index.md index c00e44c0..5abc2b35 100644 --- a/api/index.md +++ b/api/index.md @@ -366,7 +366,6 @@ test.fails('fail test', async () => { ### test.each -- **类型:** `(cases: ReadonlyArray, ...args: any[]) => void` - **别名:** `it.each` ::: tip @@ -426,6 +425,11 @@ test.each([ ])('add($0, $1) -> $2', (a, b, expected) => { expect(a + b).toBe(expected) }) + +// 这将返回 +// ✓ add(1, 1) -> 2 +// ✓ add(1, 2) -> 3 +// ✓ add(2, 1) -> 3 ``` 如果使用对象作为参数,你也可以使用 `.` 来访问对象属性: @@ -453,33 +457,12 @@ test.each([ import { expect, test } from 'vitest' test.each` - a | b | expected - ${{ val: 1 }} | ${'b'} | ${'1b'} - ${{ val: 2 }} | ${'b'} | ${'2b'} - ${{ val: 3 }} | ${'b'} | ${'3b'} -`('add($a.val, $b) -> $expected', ({ a, b, expected }) => { - expect(a.val + b).toBe(expected) -}) - -// 这将返回 -// ✓ add(1, b) -> 1b -// ✓ add(2, b) -> 2b -// ✓ add(3, b) -> 3b -``` - -从 Vitest 0.25.3 开始,还可以使用模板字符串表。 - -- 第一行应为列名,用 `|` 分隔; -- 使用 `${value}` 语法,以模板字面表达式的形式提供后面一行或多行数据。 - -```ts -test.each` - a | b | expected - ${1} | ${1} | ${2} - ${'a'} | ${'b'} | ${'ab'} - ${[]} | ${'b'} | ${'b'} - ${{}} | ${'b'} | ${'[object Object]b'} - ${{ asd: 1 }} | ${'b'} | ${'[object Object]b'} + a | b | expected + ${1} | ${1} | ${2} + ${'a'} | ${'b'} | ${'ab'} + ${[]} | ${'b'} | ${'b'} + ${{}} | ${'b'} | ${'[object Object]b'} + ${{ asd: 1 }} | ${'b'} | ${'[object Object]b'} `('returns $expected when $a is added $b', ({ a, b, expected }) => { expect(a + b).toBe(expected) }) From d966f0af63e03288e2a4ba14ab31c2f4cf5f6171 Mon Sep 17 00:00:00 2001 From: noise Date: Wed, 7 Jan 2026 21:59:43 +0800 Subject: [PATCH 10/31] docs(cn): update guide/browser/component-testing --- guide/browser/component-testing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/guide/browser/component-testing.md b/guide/browser/component-testing.md index bfee1989..549b9f04 100644 --- a/guide/browser/component-testing.md +++ b/guide/browser/component-testing.md @@ -263,7 +263,7 @@ test('ShoppingCart manages items correctly', async () => { import { http, HttpResponse } from 'msw' import { setupWorker } from 'msw/browser' -// 使用 API 处理程序设置 MSW worker +// 使用 MSW Worker 初始化 API 处理程序 const worker = setupWorker( http.get('/api/users/:id', ({ params }) => { // 描述成功路径 @@ -283,7 +283,7 @@ test('UserProfile handles loading, success, and error states', async () => { await expect.element(getByText('John Doe')).toBeInTheDocument() await expect.element(getByText('john@example.com')).toBeInTheDocument() - // 通过为此测试覆盖处理程序来测试错误状态 + // 通过为此测试覆盖处理程序,来测试错误状态 worker.use( http.get('/api/users/:id', () => { return HttpResponse.json({ error: 'User not found' }, { status: 404 }) @@ -296,7 +296,7 @@ test('UserProfile handles loading, success, and error states', async () => { ``` ::: tip -查看更多关于[在浏览器中使用 MSW](https://mswjs.io/docs/integrations/browser) 的详细信息。 +更多内容请参阅 [在浏览器中使用 MSW](https://mswjs.io/docs/integrations/browser)。 ::: ### 测试组件通信 {#testing-component-communication} From af18bc907c3b5a2ec0d77ead5dca9027bfb3263b Mon Sep 17 00:00:00 2001 From: noise Date: Thu, 8 Jan 2026 00:16:23 +0800 Subject: [PATCH 11/31] docs(cn): update guide/profiling-test-performance --- guide/profiling-test-performance.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/guide/profiling-test-performance.md b/guide/profiling-test-performance.md index ba2684a5..488e0ab0 100644 --- a/guide/profiling-test-performance.md +++ b/guide/profiling-test-performance.md @@ -15,11 +15,11 @@ > # Time metrics ^^ > ``` -- Transform:转换文件所花费的时间。参见 [文件转换](#file-transform)。 -- Setup:运行 [`setupFiles`](/config/#setupfiles) 文件所花费的时间。 +- Transform:转换文件所用的时间。详情请参阅 [文件转换](#file-transform)。 +- Setup:执行 [`setupFiles`](/config/#setupfiles) 文件所花费的时间。 - Import:导入测试文件及其依赖项所花费的时间。这也包括收集所有测试所花费的时间。注意,这不包括测试内部的动态导入。 -- Tests:实际运行测试用例所花费的时间。 -- Environment:设置测试 [`environment`](/config/#environment) 所花费的时间,例如 JSDOM。 +- Tests:实际执行测试用例所用的时间。 +- Environment:[`配置测试`](/config/#environment) 环境(比如 JSDOM)所需的时间。 ## 测试运行器 {#test-runner} From 7c5062b548f28893a826259baa86651ececbf348 Mon Sep 17 00:00:00 2001 From: noise Date: Thu, 8 Jan 2026 20:13:57 +0800 Subject: [PATCH 12/31] docs(cn): update api/browser/locators --- api/browser/locators.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api/browser/locators.md b/api/browser/locators.md index 67eba258..d814ded3 100644 --- a/api/browser/locators.md +++ b/api/browser/locators.md @@ -237,26 +237,26 @@ function getByLabelText( 下方示例中,`page.getByLabelText('Username')` 会一次性选中所有相关输入框。 ```html -// for/htmlFor relationship between label and form element id +// for/htmlFor 标签与表单元素 ID 的关系 -// The aria-labelledby attribute with form elements +// 使用 aria-labelledby 属性与表单元素 // 包裹式标签 -// 标签文本在另一个子元素中的包裹式标签 +// 标签文本位于其他子元素中的包裹式标签 // aria-label 属性 -// 请注意,这不是用户在页面上能看到的标签, -// 因此输入框的用途必须对视觉用户来说是显而易见的。 +// 注意:这不是用户在页面上可见的标签 +// 因此输入的目的必须对视觉障碍用户显而易见。 ``` From 1995a514c8a1d5dbedc0c59b758cbb7610b94b92 Mon Sep 17 00:00:00 2001 From: noise Date: Thu, 8 Jan 2026 20:23:54 +0800 Subject: [PATCH 13/31] docs(cn): update api/expect --- api/expect.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/expect.md b/api/expect.md index d545bc9c..da0ae481 100644 --- a/api/expect.md +++ b/api/expect.md @@ -382,7 +382,7 @@ test('getApplesCount has some unusual side effects...', () => { - **类型:** `(sample: Array | Set) => any` -`toBeOneOf` 断言一个值是否匹配提供的数组或集合中的任意一个值。 +`toBeOneOf` 断言一个值是否与提供的数组或集合中的任意一个值相匹配。 ::: warning 实验性功能 提供 `Set` 是一个实验性功能,可能会在未来版本中发生变化。 @@ -722,7 +722,7 @@ import { expect, test } from 'vitest' test('top fruits', () => { expect('top fruits include apple, orange and grape').toMatch(/apple/) - expect('applefruits').toMatch('fruit') // toMatch 也接受字符串 + expect('applefruits').toMatch('fruit') // toMatch 也接受字符串作为参数 }) ``` From 46bc3383112585305b54d68f9b58c1a171115f90 Mon Sep 17 00:00:00 2001 From: noise Date: Sun, 11 Jan 2026 21:08:56 +0800 Subject: [PATCH 14/31] docs(cn): update guide/parallelism --- guide/parallelism.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guide/parallelism.md b/guide/parallelism.md index c0a515ba..23c96ac6 100644 --- a/guide/parallelism.md +++ b/guide/parallelism.md @@ -12,7 +12,7 @@ outline: deep - `forks`(默认)和 `vmForks` 会在不同的 [child processes](https://nodejs.org/api/child_process.html) 中执行测试 - `threads` 和 `vmThreads` 则会在不同的 [worker threads](https://nodejs.org/api/worker_threads.html) 中运行 -"子进程(child processes)"和"工作线程(worker threads)"统称为"工作者(workers)"。你可以通过 [`maxWorkers`](/config/#maxworkers) 选项来配置运行的工作者数量。 +“子进程(child processes)” 和 “工作线程(worker threads)” 都统称为 “工作者(workers)”。你可以通过 [`maxWorkers`](/config/#maxworkers) 选项配置运行的工作者数量。 如果项目包含大量测试文件,通常并行执行会大幅提升速度。但具体效果还要看项目本身、运行环境以及是否启用了 [隔离](/config/#isolate)。若需要关闭文件级并行化,可以将 [`fileParallelism`](/config/#fileparallelism) 设为 `false` 。更多性能优化技巧,请参考 [性能指南](/guide/improving-performance) 。 From 80b43fe202720a31c793faaf91dd80c8e3ba4dbe Mon Sep 17 00:00:00 2001 From: noise Date: Sun, 11 Jan 2026 23:07:14 +0800 Subject: [PATCH 15/31] docs(cn): update config/resolvesnapshotpath --- config/resolvesnapshotpath.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/resolvesnapshotpath.md b/config/resolvesnapshotpath.md index 6bb1f5cc..1baa472f 100644 --- a/config/resolvesnapshotpath.md +++ b/config/resolvesnapshotpath.md @@ -8,7 +8,7 @@ outline: deep - **类型**: `(testPath: string, snapExtension: string, context: { config: SerializedConfig }) => string` - **默认值**: 将快照文件存储在 `__snapshots__` 目录中 -覆盖默认的快照路径。例如,将快照存储在测试文件旁边: +覆盖默认的快照路径。例如,将快照文件与测试文件存放在同一目录下: ```ts import { defineConfig } from 'vitest/config' @@ -20,7 +20,7 @@ export default defineConfig({ }) ``` -你还可以使用 `context` 参数来访问项目的序列化配置。当你有多个 [项目](/guide/projects) 并希望根据项目名称将快照存储在不同位置时,这很有用: +你还可以使用 `context` 参数来访问项目的序列化配置。当你配置了多个 [项目](/guide/projects) 并希望根据项目名称将快照存储在不同位置时,这很有用: ```ts import { basename, dirname, join } from 'node:path' From 672de47b19f5fc71f9518e5727a2d069b3c8e179 Mon Sep 17 00:00:00 2001 From: noise Date: Sun, 11 Jan 2026 23:19:06 +0800 Subject: [PATCH 16/31] docs(cn): update guide/browser/index.md --- guide/browser/index.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/guide/browser/index.md b/guide/browser/index.md index e6ac3fb9..db5ea1c8 100644 --- a/guide/browser/index.md +++ b/guide/browser/index.md @@ -1,11 +1,11 @@ --- -title: Browser Mode | Guide +title: 浏览器模式 | 指南 outline: deep --- # 浏览器模式 {#browser-mode} -本页面提供了关于 Vitest API 中浏览器模式功能的信息,该功能允许你在浏览器中原生运行测试,提供对浏览器全局变量(如 window 和 document)的访问。 +本章介绍 Vitest API 中浏览器模式功能,该功能允许你在浏览器中运行测试,从而可直接访问 window 和 document 等浏览器全局对象。 ::: tip 如果你需要 `expect` 、`vi` ,或者像测试项目、类型测试等通用 API 的文档,请查看 [“快速起步” 指南](/guide/)。 @@ -35,9 +35,9 @@ bunx vitest init browser ### 手动安装 {#manual-installation} -你也可以手动安装包。Vitest 始终需要定义一个提供程序。你可以选择 [`preview`](/config/browser/preview)、[`playwright`](/config/browser/playwright) 或 [`webdriverio`](/config/browser/webdriverio)。 +你也可以手动安装依赖包。Vitest 明确要求定义一个 provider。你可以选择 [`preview`](/config/browser/preview)、[`playwright`](/config/browser/playwright) 或 [`webdriverio`](/config/browser/webdriverio)。 -如果你只想预览测试的外观,可以使用 `preview` 提供程序: +如果你仅需预览测试运行效果,可以使用 `preview` 提供程序: ::: code-group ```bash [npm] @@ -57,7 +57,7 @@ bun add -D vitest @vitest/browser-preview ::: warning 不过,要在 CI 中运行测试,我们需要安装 [`playwright`](https://npmjs.com/package/playwright) 或 [`webdriverio`](https://www.npmjs.com/package/webdriverio) 。我们还建议在本地测试时切换到这两个选项中的一个,而不是使用默认的 `preview` 提供程序,因为它依赖于模拟事件而不是使用 Chrome DevTools 协议。 -如果你还没有使用这些工具中的任何一个,我们建议从 Playwright 开始,因为它支持并行执行,这使你的测试运行得更快。 +如果你还没有使用这些工具中的任何一个,我们建议从 Playwright 开始,因为它支持并行执行,可显著提升测试速度。 ::: tabs key:provider == Playwright From 5dfb152911e5fc22bc47444b808730af6e9df443 Mon Sep 17 00:00:00 2001 From: noise Date: Sun, 11 Jan 2026 23:58:20 +0800 Subject: [PATCH 17/31] docs(cn): update guide/comparisons.md --- guide/comparisons.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/guide/comparisons.md b/guide/comparisons.md index b449091a..69377561 100644 --- a/guide/comparisons.md +++ b/guide/comparisons.md @@ -56,29 +56,29 @@ uvu 是运行简单测试的快速选项, 但对于更复杂的测试和项目, ## Mocha -[Mocha](https://mochajs.org) 是一个在 Node.js 和浏览器中运行的测试框架。Mocha 是服务器端测试的热门选择。Mocha 高度可配置,默认情况下不包含某些功能。例如,它不自带断言库,其理念是 Node 的内置断言运行器对大多数用例来说已经足够好了。在 Mocha 中,另一个流行的断言库选择是 [Chai](https://www.chaijs.com)。 +[Mocha](https://mochajs.org) 是一个可在 Node.js 和浏览器中运行的测试框架。Mocha 是服务器端测试的热门选择。Mocha 具有高度可配置性且默认不包含某些功能。例如,它不内置断言库,因为 Node 的原生断言运行器已能满足大多数场景需求。在 Mocha 中,与 Mocha 搭配使用的流行断言库还包括 [Chai](https://www.chaijs.com)。 -Vitest 还为一些其他功能提供了开箱即用的设置,而这些功能在 Mocha 中需要额外的配置或添加其他库,例如: +Vitest 则开箱即用,提供了多项需要 Mocha 额外配置或引入其他库才能实现的功能,例如: - 快照测试 - TypeScript - JSX 支持 - 代码覆盖率 - 模拟对象(Mocking) -- 智能观察模式(仅重新运行受影响的测试) +- 智能监听模式(仅重新运行受影响的测试) -虽然 Mocha 支持原生 ESM,但它有一些限制和配置约束。例如,观察模式不能与 ES 模块文件一起使用。 +尽管 Mocha 支持原生 ESM,但存在功能限制和配置约束。例如监听模式无法处理 ES 模块文件。 -在性能方面,Mocha 默认串行运行测试,但支持使用 `--parallel` 标志进行并行执行(尽管某些报告器和功能在并行模式下不起作用)。 +在性能方面,Mocha 默认串行运行测试,但支持使用 `--parallel` 标志启用并行执行(不过部分报告器和功能在并行模式下不可用)。 -如果你已经在构建管道中使用 Vite,Vitest 允许你重用相同的配置和插件进行测试,而 Mocha 则需要单独的测试设置。Vitest 提供了与 Jest 兼容的 API,同时也支持 Mocha 熟悉的 `describe`、`it` 和钩子语法,使大多数测试套件的迁移变得简单直接。 +如果你的构建流程已使用 Vite,Vitest 允许复用相同的配置和插件进行测试,而 Mocha 则需要独立的测试配置。Vitest 提供与 Jest 兼容的 API,同时支持 Mocha 惯用的 `describe`、`it` 和钩子语法,使得大多数测试套件的迁移非常便捷。 -Mocha 对于需要最小化、灵活的测试运行器并完全控制其测试堆栈的项目来说,仍然是一个可靠的选择。然而,如果你想要一个开箱即用的现代测试体验——特别是对于 Vite 驱动的应用程序——Vitest 可以满足你的需求。 +Mocha 对于需要最小化、灵活的测试运行器并完全控制其测试堆栈的项目来说,仍然是一个可靠的选择。然而,如果你想要一个开箱即用的现代测试体验 —— 特别是对于 Vite 驱动的应用程序 —— Vitest 将会是更优的解决方案。 ## Playwright -[Playwright](https://playwright.dev) 是微软推出的一个测试框架,擅长跨多个浏览器(Chromium、Firefox 和 WebKit)进行端到端测试。它控制真实的浏览器来测试完整的用户工作流程——从登录和导航应用程序到提交表单和验证结果。另一方面,Vitest 针对无头环境中的快速、隔离的单元测试和组件测试进行了优化。这些差异使它成为 Vitest 的理想补充。 +[Playwright](https://playwright.dev) 是微软推出的测试框架,擅长跨浏览器(Chromium、Firefox 和 WebKit)的端到端测试。它通过控制真实的浏览器来验证完整的用户流程 —— 从登录到导航至提交表单与结果验证。而 Vitest 则针对无头环境中的快速、隔离单元测试和组件测试进行了优化。这些差异使它成为 Vitest 的理想补充方案。 -标准的设置是将 Vitest 用于所有单元测试和组件测试(业务逻辑、工具函数、钩子和 UI 组件测试),将 Playwright 用于验证关键用户路径和跨浏览器兼容性的端到端测试。这种组合让你在开发过程中通过 Vitest 获得快速反馈,同时通过 Playwright 确保完整的应用程序在真实浏览器中正常工作。 +标准的配置是采用 Vitest 执行所有单元测试和组件测试(业务逻辑、工具函数、钩子和 UI 组件测试),同时使用 Playwright 进行关键用户路径测试和跨浏览器兼容性的端到端测试。这种组合既能通过 Vitest 在开发阶段快速获得反馈,又能利用 Playwright 确保完整的应用程序在真实浏览器中正常运行。 -Vitest 最近引入了[浏览器模式](https://vitest.dev/api/browser),可以在真实浏览器中运行测试。然而,存在关键的架构差异:Playwright 组件测试在 Node.js 进程中运行并远程控制浏览器。Vitest 的浏览器模式在浏览器中原生运行测试,与 Vitest 的测试运行器和开发者体验保持一致,但它确实有一些[限制](/guide/browser/#limitations)。 +Vitest 近期推出了 [浏览器模式](/api/browser),支持在真实浏览器中运行测试。然而,两者存在关键架构差异:Playwright 的组件测试运行于 Node.js 进程并远程控制浏览器,而 Vitest Vitest 的浏览器模式在浏览器中原生运行测试,虽然保持了与 Vitest 测试运行器及开发者体验的一致性,但它确实有一些[限制](/guide/browser/#limitations)。 From 1a452484f27360c80387f256018e3368a1cf2ede Mon Sep 17 00:00:00 2001 From: noise Date: Mon, 12 Jan 2026 00:49:34 +0800 Subject: [PATCH 18/31] docs(cn): update guide/comparisons.md --- guide/comparisons.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/guide/comparisons.md b/guide/comparisons.md index 69377561..209a0237 100644 --- a/guide/comparisons.md +++ b/guide/comparisons.md @@ -56,9 +56,9 @@ uvu 是运行简单测试的快速选项, 但对于更复杂的测试和项目, ## Mocha -[Mocha](https://mochajs.org) 是一个可在 Node.js 和浏览器中运行的测试框架。Mocha 是服务器端测试的热门选择。Mocha 具有高度可配置性且默认不包含某些功能。例如,它不内置断言库,因为 Node 的原生断言运行器已能满足大多数场景需求。在 Mocha 中,与 Mocha 搭配使用的流行断言库还包括 [Chai](https://www.chaijs.com)。 +[Mocha](https://mochajs.org) 是一个可在 Node.js 和浏览器中运行的测试框架。作为服务器端测试的主流选择。它具有高度可配置性,且默认不包含某些功能。例如,它不内置断言库,其设计理念是 Node 的原生断言运行器已能满足大多数场景需求。与 Mocha 搭配使用的主流断言库是 [Chai](https://www.chaijs.com)。 -Vitest 则开箱即用,提供了多项需要 Mocha 额外配置或引入其他库才能实现的功能,例如: +Vitest 还针对多项功能提供了开箱即用的支持,而这些功能在 Mocha 中需要额外配置或引入其他库才能实现,例如: - 快照测试 - TypeScript @@ -81,4 +81,4 @@ Mocha 对于需要最小化、灵活的测试运行器并完全控制其测试 标准的配置是采用 Vitest 执行所有单元测试和组件测试(业务逻辑、工具函数、钩子和 UI 组件测试),同时使用 Playwright 进行关键用户路径测试和跨浏览器兼容性的端到端测试。这种组合既能通过 Vitest 在开发阶段快速获得反馈,又能利用 Playwright 确保完整的应用程序在真实浏览器中正常运行。 -Vitest 近期推出了 [浏览器模式](/api/browser),支持在真实浏览器中运行测试。然而,两者存在关键架构差异:Playwright 的组件测试运行于 Node.js 进程并远程控制浏览器,而 Vitest Vitest 的浏览器模式在浏览器中原生运行测试,虽然保持了与 Vitest 测试运行器及开发者体验的一致性,但它确实有一些[限制](/guide/browser/#limitations)。 +Vitest 近期推出了 [浏览器模式](/guide/browser),支持在真实浏览器中运行测试。然而,两者存在关键架构差异:Playwright 的组件测试运行于 Node.js 进程并远程控制浏览器,而 Vitest Vitest 的浏览器模式在浏览器中原生运行测试,虽然保持了与 Vitest 测试运行器及开发者体验的一致性,但它确实有一些 [限制](/guide/browser/#limitations)。 From 42590c7583f6faa78922ea5f1d0a16f2a400c995 Mon Sep 17 00:00:00 2001 From: noise Date: Mon, 12 Jan 2026 01:09:50 +0800 Subject: [PATCH 19/31] docs(cn): update guide/mocking/modules.md --- guide/comparisons.md | 2 +- guide/mocking/modules.md | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/guide/comparisons.md b/guide/comparisons.md index 209a0237..195abb7c 100644 --- a/guide/comparisons.md +++ b/guide/comparisons.md @@ -81,4 +81,4 @@ Mocha 对于需要最小化、灵活的测试运行器并完全控制其测试 标准的配置是采用 Vitest 执行所有单元测试和组件测试(业务逻辑、工具函数、钩子和 UI 组件测试),同时使用 Playwright 进行关键用户路径测试和跨浏览器兼容性的端到端测试。这种组合既能通过 Vitest 在开发阶段快速获得反馈,又能利用 Playwright 确保完整的应用程序在真实浏览器中正常运行。 -Vitest 近期推出了 [浏览器模式](/guide/browser),支持在真实浏览器中运行测试。然而,两者存在关键架构差异:Playwright 的组件测试运行于 Node.js 进程并远程控制浏览器,而 Vitest Vitest 的浏览器模式在浏览器中原生运行测试,虽然保持了与 Vitest 测试运行器及开发者体验的一致性,但它确实有一些 [限制](/guide/browser/#limitations)。 +Vitest 近期推出了 [浏览器模式](/guide/browser/),支持在真实浏览器中运行测试。然而,两者存在关键架构差异:Playwright 的组件测试运行于 Node.js 进程并远程控制浏览器,而 Vitest Vitest 的浏览器模式在浏览器中原生运行测试,虽然保持了与 Vitest 测试运行器及开发者体验的一致性,但它确实有一些 [限制](/guide/browser/#limitations)。 diff --git a/guide/mocking/modules.md b/guide/mocking/modules.md index a47b4077..436ba057 100644 --- a/guide/mocking/modules.md +++ b/guide/mocking/modules.md @@ -2,7 +2,7 @@ ## 模块的定义 {#defining-a-module} -在模拟“模块”之前,我们应该定义它是什么。在 Vitest 上下文中,“模块”是导出某些内容的文件。使用 [插件](https://vite.dev/guide/api-plugin.html),任何文件都可以转换为 JavaScript 模块。"模块对象"是一个命名空间对象,它保存对导出标识符的动态引用。简单来说,它是一个具有导出方法和属性的对象。在此示例中,`example.js` 是一个导出 `answer` 和 `variable` 的模块: +在模拟一个 “模块” 之前,我们首先需要明确其定义。在 Vitest 上下文中,“模块” 是指导出某些内容的文件。通过 [Vite 插件](https://vite.dev/guide/api-plugin.html),任何文件都可以被转为 JavaScript 模块。而 “模拟对象” 则是一个摸命名空间对象,它持有对导出标识符的动态引用。简而言之,模拟对象就是一个包含导出方法的和属性的普通对象。在以下示例中,`example.js` 就是一个导出 `answer` 和 `variable` 的模块: ```js [example.js] export function answer() { @@ -42,9 +42,8 @@ import { answer, variable } from './example.js' ```ts import { vi } from 'vitest' -// ./example.js 模块将被替换为 -// 工厂函数的结果,并且 -// 原始的 ./example.js 模块将永远不会被调用 +// ./example.js 模块将被替换为工厂函数的执行结果 +// 而原始的 ./example.js 模块将永远不会被调用 vi.mock(import('./example.js'), () => { return { answer() { @@ -334,8 +333,7 @@ vi.mock('./answer.js') const __vitest_module_0__ = await __handle_mock__( () => import('./answer.js') ) -// 为了保持实时绑定,我们必须通过 -// 模块命名空间来访问导出 +// 为了保持实时绑定,我们必须通过模块命名空间上的导出 console.log(__vitest_module_0__.answer()) ``` ::: From 69d6545b15354b43f26ec1abc1bdc65e00b23dec Mon Sep 17 00:00:00 2001 From: noise Date: Mon, 12 Jan 2026 01:18:09 +0800 Subject: [PATCH 20/31] docs(cn): update guide/browser/component-testing.md --- guide/browser/component-testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guide/browser/component-testing.md b/guide/browser/component-testing.md index 549b9f04..ec9bbb27 100644 --- a/guide/browser/component-testing.md +++ b/guide/browser/component-testing.md @@ -259,7 +259,7 @@ test('ShoppingCart manages items correctly', async () => { ### 测试带有数据获取的异步组件 {#testing-async-components-with-data-fetching} ```tsx -// 选项 1:推荐 - 使用 MSW(Mock Service Worker)进行 API 模拟 +// 选项 1(推荐):使用 MSW(Mock Service Worker)进行 API 模拟 import { http, HttpResponse } from 'msw' import { setupWorker } from 'msw/browser' From 29f59d3267d9de39cb14d808766aa7f649212059 Mon Sep 17 00:00:00 2001 From: noise Date: Mon, 12 Jan 2026 01:21:51 +0800 Subject: [PATCH 21/31] docs(cn): update guide/features.md --- guide/features.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/guide/features.md b/guide/features.md index eb878597..ed020709 100644 --- a/guide/features.md +++ b/guide/features.md @@ -42,6 +42,8 @@ $ vitest 默认情况下,Vitest 使用 [`node:child_process`](https://nodejs.org/api/child_process.html) 在[多个进程](/guide/parallelism)中运行测试文件,允许测试同时运行。如果你想进一步加快测试套件的速度,可以考虑启用 `--pool=threads` 来使用 [`node:worker_threads`](https://nodejs.org/api/worker_threads.html) 运行测试(请注意,某些包可能无法在此设置下工作)。 要在单个线程或进程中运行测试,请参阅 [`fileParallelism`](/config/#fileParallelism)。 +默认情况下,Vitest 会通过 [`node:child_process`](https://nodejs.org/api/child_process.html) 在 [多个进程](/guide/parallelism) 中运行测试文件,实现测试的并行执行。如需进一步提升测试速度,可考虑启用 `--pool=threads` 参数改用 [`node:worker_threads`](https://nodejs.org/api/worker_threads.html) 运行测试(但需注意某些依赖包可能不兼容此模式)。若需在单线程/进程中运行测试,请参阅 [`fileParallelism`](/config/#fileParallelism) 配置项。 + Vitest 还隔离了每个测试文件的运行环境,因此一个文件中的运行环境改变不会影响其他文件。可以通过将 `--no-isolate` 传递给 CLI 来禁用隔离(以正确性换取运行性能)。 ## 测试可过滤 {#test-filtering} From f4dddd826d4f4ea38223b748c00a7ac2a541edc5 Mon Sep 17 00:00:00 2001 From: noise Date: Mon, 12 Jan 2026 01:42:51 +0800 Subject: [PATCH 22/31] docs(cn): update guide/migration.md --- guide/migration.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/guide/migration.md b/guide/migration.md index 6cc0a421..af76e31a 100644 --- a/guide/migration.md +++ b/guide/migration.md @@ -24,7 +24,7 @@ Vitest 的 V8 覆盖率提供器现在使用了更精准的结果映射逻辑, 然而,这导致 Vitest 覆盖率工具会处理很多意料之外的文件(例如压缩 JS 文件),造成报告生成速度很慢甚至卡死。在 Vitest v4 中,我们彻底移除了 `coverage.all`,并将默认行为改为**只在报告中包含被测试覆盖的文件**。 -When upgrading to v4 it is recommended to define `coverage.include` in your configuration, and then start applying simple `coverage.exclude` patterns if needed. +升级至 v4 版本时,建议先在配置文件中定义 `coverage.include`,再根据需要逐步添加简单的 `coverage.exclude` 匹配规则。 ```ts [vitest.config.ts] export default defineConfig({ @@ -66,13 +66,13 @@ export default defineConfig({ ### 简化的 `exclude` 配置 {#simplified-exclude} -默认情况下,Vitest 现在只从 `node_modules` 和 `.git` 文件夹中排除测试。这意味着 Vitest 不再排除: +默认情况下,Vitest 现在仅排除 `node_modules` 和 `.git` 文件夹中的测试文件。这意味着 Vitest 不再排除以下内容: - `dist` 和 `cypress` 文件夹 - `.idea`、`.cache`、`.output`、`.temp` 文件夹 - 配置文件,如 `rollup.config.js`、`prettier.config.js`、`ava.config.js` 等 -如果你需要限制测试文件所在的目录,请使用 [`test.dir`](/config/dir) 选项,因为它比排除文件更高效: +如果需要限制测试文件所在的目录,建议使用 [`test.dir`](/config/dir) 选项,因为它的性能优于排除文件: ```ts import { configDefaults, defineConfig } from 'vitest/config' @@ -102,9 +102,9 @@ export default defineConfig({ }) ``` -### `spyOn` and `fn` Support Constructors +### `spyOn` 和 `fn` 支持构造函数 {#spyon-and-fn-support-constructors} -Previously, if you tried to spy on a constructor with `vi.spyOn`, you would get an error like `Constructor requires 'new'`. Since Vitest 4, all mocks called with a `new` keyword construct the instance instead of calling `mock.apply`. This means that the mock implementation has to use either the `function` or the `class` keyword in these cases: +在之前的版本中,如果尝试使用 `vi.spyOn` 监视构造函数,可能会收到类似 `Constructor requires 'new'` 的错误。自 Vitest 4 起,所有通过 `new` 关键字调用的模拟会构造实例,而不是调用 `mock.apply`。这意味着在这些情况下,模拟实现必须使用 `function` 或 `class` 关键字: ```ts {12-14,16-20} const cart = { @@ -135,13 +135,14 @@ const mock = new Spy() ### Mock 的变更 {#changes-to-mocking} -Alongside new features like supporting constructors, Vitest 4 creates mocks differently to address several module mocking issues that we received over the years. This release attempts to make module spies less confusing, especially when working with classes. +除了新增对构造函数的支持等功能外,Vitest 4 还对模拟的创建方式进行了调整,以解决多年来我们收到的多个模块模拟问题。此版本试图减少模块监视的混淆,尤其是在处理类时。 + +- `vi.fn().getMockName()` 现在默认返回 `vi.fn()` 而非 `spy`。这可能会影响包含模拟的快照 —— 名称将从 `[MockFunction spy]` 改为 `[MockFunction]`。通过 `vi.spyOn` 创建的监视器默认仍会使用原始名称,以提供更好的调试体验。 +- `vi.restoreAllMocks` 不再重置监视器的状态,仅恢复通过 `vi.spyOn` 手动创建的监视器,自动模拟不再受此函数影响(这也影响了配置选项 [`restoreMocks`](/config/#restoremocks))。需注意的是,`.mockRestore` 仍会重置模拟实现并清除状态。 +- 对模拟调用 `vi.spyOn` 现在会返回相同的模拟。 +- `mock.settledResults` 现在会在函数调用时立即填充一个 `'incomplete'` 结果。当 Promise 完成时,类型会根据结果更新。 +- 自动模拟的实例方法现在已正确隔离,但仍与原型共享状态。除非实例方法有自己的自定义模拟实现,否则覆盖原型实现将始终影响实例方法。对模拟调用 `.mockReset` 也不再破坏这种继承关系。 -- `vi.fn().getMockName()` now returns `vi.fn()` by default instead of `spy`. This can affect snapshots with mocks - the name will be changed from `[MockFunction spy]` to `[MockFunction]`. Spies created with `vi.spyOn` will keep using the original name by default for better debugging experience -- `vi.restoreAllMocks` no longer resets the state of spies and only restores spies created manually with `vi.spyOn`, automocks are no longer affected by this function (this also affects the config option [`restoreMocks`](/config/#restoremocks)). Note that `.mockRestore` will still reset the mock implementation and clear the state -- Calling `vi.spyOn` on a mock now returns the same mock -- `mock.settledResults` are now populated immediately on function invocation with an `'incomplete'` result. When the promise is finished, the type is changed according to the result. -- Automocked instance methods are now properly isolated, but share a state with the prototype. Overriding the prototype implementation will always affect instance methods unless the methods have a custom mock implementation of their own. Calling `.mockReset` on the mock also no longer breaks that inheritance. ```ts import { AutoMockedClass } from './example.js' const instance1 = new AutoMockedClass() @@ -303,6 +304,7 @@ const { getElementError } = utils // [!code ++] 在过渡期间,`@vitest/browser/context` 和 `@vitest/browser/utils` 都能在运行时工作,但它们将在未来的版本中移除。 ::: + ### Pool Rework Vitest has used [`tinypool`](https://github.com/tinylibs/tinypool) for orchestrating how test files are run in the test runner workers. Tinypool has controlled how complex tasks like parallelism, isolation and IPC communication works internally. However we've found that Tinypool has some flaws that are slowing down development of Vitest. In Vitest v4 we've completely removed Tinypool and rewritten how pools work without new dependencies. Read more about reasoning from [feat!: rewrite pools without tinypool #8705 @@ -403,6 +405,7 @@ export default defineConfig({ See [Recipes](/guide/recipes) for more examples. + ### Reporter Updates Reporter APIs `onCollected`, `onSpecsCollected`, `onPathsCollected`, `onTaskUpdate` and `onFinished` were removed. See [`Reporters API`](/api/advanced/reporters) for new alternatives. The new APIs were introduced in Vitest `v3.0.0`. @@ -559,6 +562,7 @@ Vitest 的测试名使用 `>` 符号连接,方便区分测试与套件,而 J ``` ### 环境变量 {#envs} + Just like Jest, Vitest sets `NODE_ENV` to `test`, if it wasn't set before. Vitest also has a counterpart for `JEST_WORKER_ID` called `VITEST_POOL_ID` (always less than or equal to `maxWorkers`), so if you rely on it, don't forget to rename it. Vitest also exposes `VITEST_WORKER_ID` which is a unique ID of a running worker - this number is not affected by `maxWorkers`, and will increase with each created worker. From 64e55aadaaa5a256a8eec5b17cd4ee44fee12792 Mon Sep 17 00:00:00 2001 From: noise Date: Tue, 13 Jan 2026 20:38:54 +0800 Subject: [PATCH 23/31] docs(cn): update config/browser.md --- config/browser.md | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/config/browser.md b/config/browser.md index 84390037..4c095f74 100644 --- a/config/browser.md +++ b/config/browser.md @@ -1,8 +1,9 @@ --- -title: 浏览器配置参考 | 配置 +title: 浏览器配置 | 配置 outline: deep --- -# 浏览器配置参考 {#browser-config-reference} + +# 浏览器配置 {#browser-config-reference} 我们可以通过更新 [配置文件](/config/) 中的 `test.browser` 字段来更改浏览器配置。一个简单的配置文件示例如下: @@ -26,7 +27,7 @@ export default defineConfig({ }) ``` -请参阅 ["配置参考"](/config/) 文章以获取不同的配置示例。 +请参阅 [“配置文件”](/config/) 文章以获取不同的配置示例。 ::: warning 此页面上列出的 _所有选项_ 都位于配置中的 `test` 属性内: @@ -53,9 +54,9 @@ export default defineConfig({ - **类型:** `BrowserConfig` - **默认值:** `[]` -定义多个浏览器设置。每个配置必须至少有一个 `browser` 字段。 +定义多个浏览器实例。每个配置必须至少有一个 `browser` 字段。 -你可以指定大多数 [项目选项](/config/)(未标记 图标的)和一些 `browser` 选项,如 `browser.testerHtmlPath`。 +你可以指定大多数 [项目选项](/config/)(未标记 图标的)和一些 `browser` 配置项,如 `browser.testerHtmlPath`。 ::: warning 每个浏览器配置都从根配置继承选项: @@ -490,9 +491,9 @@ resolveDiffPath: ({ arg, attachmentsDir, browserName, ext, root, testFileName }) - **类型:** `Record` -注册自定义截图比较算法,如 [SSIM](https://en.wikipedia.org/wiki/Structural_similarity_index_measure) 或其他感知相似度指标。 +注册自定义屏幕截图比较算法,例如 [SSIM](https://en.wikipedia.org/wiki/Structural_similarity_index_measure) 或其他感知相似度指标。 -要创建自定义比较器,你需要在配置中注册它。如果使用 TypeScript,请在 `ScreenshotComparatorRegistry` 接口中声明其选项。 +要创建自定义比较器,你需要在配置文件中进行注册。如果使用 TypeScript,请将其选项声明在 `ScreenshotComparatorRegistry` 接口中。 ```ts import { defineConfig } from 'vitest/config' @@ -507,7 +508,7 @@ declare module 'vitest/browser' { } } -// 2. 实现比较器 +// 2. 实现比较器函数 export default defineConfig({ test: { browser: { @@ -523,7 +524,7 @@ export default defineConfig({ ignoreColors = false, } ) => { - // ...算法实现 + // 算法实现... return { pass, diff, message } }, }, @@ -546,7 +547,7 @@ await expect(locator).toMatchScreenshot({ }) ``` -**Comparator Function Signature:** +**比较器函数签名:** ```ts type Comparator = ( @@ -572,15 +573,15 @@ type Comparator = ( } ``` -`reference` 和 `actual` 图像使用适当的编解码器(目前仅支持 PNG)进行解码。`data` 属性是一个扁平的 `TypedArray`(`Buffer`、`Uint8Array` 或 `Uint8ClampedArray`),包含 RGBA 格式的像素数据: +`reference` 和 `actual` 图像使用对应的编解码器(目前仅支持 PNG)进行解码。`data` 属性是一个扁平的 `TypedArray`(`Buffer`、`Uint8Array` 或 `Uint8ClampedArray`),包含 RGBA 格式的像素数据: -- **每像素 4 字节**:红色、绿色、蓝色、alpha(每个从 `0` 到 `255`) -- **行主序**:像素从左到右、从上到下存储 +- **每像素 4 字节**:红色、绿色、蓝色、alpha 通道(每个从 `0` 到 `255`) +- **行主序**:像素按从左到右、从上到下的顺序存储 - **总长度**:`width × height × 4` 字节 - **Alpha 通道**:始终存在。没有透明度的图像的 alpha 值设置为 `255`(完全不透明) ::: tip 性能考虑 -`createDiff` 选项指示是否需要差异图像。在 [稳定截图检测](/guide/browser/visual-regression-testing#how-visual-tests-work) 期间,Vitest 使用 `createDiff: false` 调用比较器以避免不必要的工作。 +`createDiff` 选项指示是否需要差异图像。在 [稳定截图检测](/guide/browser/visual-regression-testing#how-visual-tests-work) 期间,Vitest 会调用比较器并设置 `createDiff: false` 以避免不必要的工作。 **尊重此标志以保持测试快速**。 ::: @@ -594,7 +595,7 @@ myCustomComparator: ( actual, { createDiff, threshold = 0.1, maxDiff = 100 }, ) => { - // ...比较逻辑 + // 比较逻辑... } ``` ::: From eb17e3fea8112ede89b33f08d70db3541d73018d Mon Sep 17 00:00:00 2001 From: noise Date: Thu, 15 Jan 2026 06:51:51 +0800 Subject: [PATCH 24/31] Merge branch 'dev' into pr-test-context-fix --- .vitepress/components/Experimental.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vitepress/components/Experimental.vue b/.vitepress/components/Experimental.vue index a528c7cc..c8b285e7 100644 --- a/.vitepress/components/Experimental.vue +++ b/.vitepress/components/Experimental.vue @@ -1,5 +1,5 @@ From 57b293225d8a8dd09eabd194de99bb65d0952733 Mon Sep 17 00:00:00 2001 From: noise Date: Thu, 15 Jan 2026 07:40:22 +0800 Subject: [PATCH 25/31] docs(cn): update config/experimental.md --- config/experimental.md | 57 +++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/config/experimental.md b/config/experimental.md index 45dd890e..8b876069 100644 --- a/config/experimental.md +++ b/config/experimental.md @@ -1,5 +1,5 @@ --- -title: experimental | Config +title: 实验性 | Config outline: deep --- @@ -14,15 +14,15 @@ outline: deep - **类型:** `boolean` - **默认值:** `false` -启用此选项允许 Vitest 将缓存的模块保存在文件系统上,使测试在重新运行之间运行得更快。 +启用此选项后, Vitest 会将缓存的模块保存在文件系统上,从而在重新运行测试时获得更快的执行速度。 你可以通过运行 [`vitest --clearCache`](/guide/cli#clearcache) 来删除旧缓存。 ::: warning 浏览器支持 -目前,此选项不影响[浏览器](/guide/browser/)。 +目前,此选项不会影响 [浏览器模式](/guide/browser/)。 ::: -你可以通过使用 `DEBUG=vitest:cache:fs` 环境变量运行 vitest 来调试模块是否被缓存: +在运行 vitest 你可以设置 `DEBUG=vitest:cache:fs` 环境变量,来调试模块是否被缓存: ```shell DEBUG=vitest:cache:fs vitest --experimental.fsModuleCache @@ -30,9 +30,9 @@ DEBUG=vitest:cache:fs vitest --experimental.fsModuleCache ### 已知问题 {#known-issues} -Vitest 基于文件内容、其 id、vite 的环境配置和覆盖率状态创建持久文件哈希。Vitest 尝试使用它拥有的关于配置的尽可能多的信息,但它仍然不完整。目前,无法跟踪你的插件选项,因为没有标准接口。 +Vitest 基于文件内容、文件 id、vite 的环境配置及覆盖率状态生成持久性文件哈希值。虽然 Vitest 会尽可能利用所有可获取的配置信息,但目前仍存在局限性。由于缺乏标准接口支持,当前无法追踪插件选项的变更情况。 -如果你有一个依赖于文件内容或公共配置之外的内容(如读取另一个文件或文件夹)的插件,缓存可能会变得陈旧。要解决这个问题,你可以定义一个[缓存键生成器](/api/advanced/plugin#definecachekeygenerator)来指定动态选项或选择不缓存该模块: +如果你的插件依赖文件内容或公开配置之外的因素(例如读取其他文件或目录),则可能出现缓存失效的情况。要解决这个问题,你可以定义一个 [缓存键生成器](/api/advanced/plugin#definecachekeygenerator) 来指定动态选项,或选择对该模块禁用缓存: ```js [vitest.config.js] import { defineConfig } from 'vitest/config' @@ -43,12 +43,12 @@ export default defineConfig({ name: 'vitest-cache', configureVitest({ experimental_defineCacheKeyGenerator }) { experimental_defineCacheKeyGenerator(({ id, sourceCode }) => { - // 永不缓存此 id + // 从不缓存此 id if (id.includes('do-not-cache')) { return false } - // 基于动态变量的值缓存此文件 + // 根据动态变量的值缓存该文件 if (sourceCode.includes('myDynamicVar')) { return process.env.DYNAMIC_VAR_VALUE } @@ -63,10 +63,9 @@ export default defineConfig({ }, }) ``` +如果你是插件作者,当你的插件可以通过不同配置选项影响转换结果时,建议在插件中定义 [缓存键生成器](/api/advanced/plugin#definecachekeygenerator)。 -如果你是插件作者,如果你的插件可以使用影响转换结果的不同选项进行注册,请考虑在插件中定义一个[缓存键生成器](/api/advanced/plugin#definecachekeygenerator)。 - -另一方面,如果你的插件不应该影响缓存键,你可以通过将 `api.vitest.experimental.ignoreFsModuleCache` 设置为 `true` 来选择退出: +另一方面,如果你的插件不应该影响缓存键,你可以通过将 `api.vitest.experimental.ignoreFsModuleCache` 设置为 `true` 来退出缓存机制: ```js [vitest.config.js] import { defineConfig } from 'vitest/config' @@ -92,7 +91,7 @@ export default defineConfig({ }) ``` -请注意,即使插件选择退出模块缓存,你仍然可以定义缓存键生成器。 +请注意,即使插件选择退出模块缓存机制,你仍然可以定义缓存键生成器。 ## experimental.fsModuleCachePath 4.0.11 {#experimental-fsmodulecachepath} @@ -101,9 +100,9 @@ export default defineConfig({ 文件系统缓存所在的目录。 -默认情况下,Vitest 会尝试找到工作区根目录并将缓存存储在 `node_modules` 文件夹中。根目录基于你的包管理器的锁文件(例如,`.package-lock.json`、`.yarn-state.yml`、`.pnpm/lock.yaml` 等)。 +默认情况下,Vitest 会尝试查找工作区根目录,并将缓存存储在 `node_modules` 文件夹中。根目录的确定基于你所使用的包管理器的锁文件(例如,`.package-lock.json`、`.yarn-state.yml`、`.pnpm/lock.yaml` 等)。 -目前,Vitest 完全忽略 [test.cache.dir](/config/cache) 或 [cacheDir](https://vite.dev/config/shared-options#cachedir) 选项,并创建一个单独的文件夹。 +目前,Vitest 会完全忽略 [test.cache.dir](/config/cache) 或 [cacheDir](https://vite.dev/config/shared-options#cachedir) 配置选项,并创建一个单独的缓存文件夹。 ## experimental.openTelemetry 4.0.11 {#experimental-opentelemetry} @@ -117,11 +116,11 @@ export default defineConfig({ interface OpenTelemetryOptions { enabled: boolean /** - * 暴露 Node.js OpenTelemetry SDK 的文件路径。 + * 暴露 Node.js OpenTelemetry SDK 的文件路径 */ sdkPath?: string /** - * 暴露浏览器 OpenTelemetry SDK 的文件路径。 + * 暴露浏览器 OpenTelemetry SDK 的文件路径 */ browserSdkPath?: string } @@ -129,17 +128,17 @@ interface OpenTelemetryOptions { - **默认值:** `{ enabled: false }` -此选项控制 [OpenTelemetry](https://opentelemetry.io/) 支持。如果 `enabled` 设置为 `true`,Vitest 会在主线程中以及每个测试文件之前导入 SDK 文件。 +此选项控制 [OpenTelemetry](https://opentelemetry.io/) 支持。当 `enabled` 设置为 `true`,Vitest 会在主线程中以及每个测试文件之前导入 SDK 文件。 -::: danger 性能注意事项 -OpenTelemetry 可能会显著影响 Vitest 性能;仅在本地调试时启用它。 +::: danger 性能警告 +OpenTelemetry 可能会显著影响 Vitest 性能;建议仅在本地调试时启用它。 ::: -你可以将[自定义服务](/guide/open-telemetry)与 Vitest 一起使用,以精确定位哪些测试或文件正在拖慢你的测试套件。 +你可以将 [自定义服务](/guide/open-telemetry) 与 Vitest 一起使用,以精确定位正在拖慢测试套件执行速度的测试或文件。 -对于浏览器模式,请参阅 OpenTelemetry 指南的[浏览器模式](/guide/open-telemetry#browser-mode)部分。 +对于浏览器模式,请参阅 OpenTelemetry 指南的 [浏览器模式](/guide/open-telemetry#browser-mode) 部分。 -`sdkPath` 相对于项目的 [`root`](/config/root) 解析,应指向一个将已启动的 SDK 实例作为默认导出暴露的模块。例如: +`sdkPath` 的路径解析相对于项目的 [`root`](/config/root) 解析,应指向一个默认导出已初始化 SDK 实例的模块。例如: ::: code-group ```js [otel.js] @@ -173,7 +172,7 @@ export default defineConfig({ ::: ::: warning -重要的是 Node 能够处理 `sdkPath` 内容,因为它不会被 Vitest 转换。请参阅[指南](/guide/open-telemetry)了解如何在 Vitest 中使用 OpenTelemetry。 +请注意 Node 必须能够直接处理 `sdkPath` 指向的内容,因为它不会被 Vitest 转换。了解如何在 Vitest 中使用 OpenTelemetry ,详情参阅 [指南](/guide/open-telemetry)。 ::: ## experimental.printImportBreakdown 4.0.15 {#experimental-printimportbreakdown} @@ -185,15 +184,15 @@ export default defineConfig({ - **类型:** `boolean` - **默认值:** `false` -在测试运行完成后显示导入耗时分解。此选项仅适用于 [`default`](/guide/reporters#default)、[`verbose`](/guide/reporters#verbose) 或 [`tree`](/guide/reporters#tree) 报告器。 +在测试运行完成后显示导入耗时明细。此选项仅适用于 [`default`](/guide/reporters#default)、[`verbose`](/guide/reporters#verbose) 或 [`tree`](/guide/reporters#tree) 报告器。 -- Self:导入模块所花费的时间,不包括静态导入; -- Total:导入模块所花费的时间,包括静态导入。请注意,这不包括当前模块的 `transform` 时间。 +- Self:模块导入耗时,不包括静态导入; +- Total:模块导入耗时,包括静态导入。请注意,这不包括当前模块的 `transform` 时间。 -终端中导入分解的示例 +终端中导入耗时明细的示例 -请注意,如果文件路径太长,Vitest 会从开头截断它,直到它符合 45 个字符的限制。 +请注意,如果文件路径太长,Vitest 会从开头截断它,最多显示 45 个字符。 ::: info -如果至少有一个文件加载时间超过 500 毫秒,[Vitest UI](/guide/ui#import-breakdown) 会自动显示导入分解。你可以手动将此选项设置为 `false` 来禁用此功能。 +[Vitest UI](/guide/ui#import-breakdown) 会在至少一个文件加载时间超过 500 毫秒时自动显示导入耗时分析。你可手动将此选项设为 `false` 来禁用该功能。 ::: From 60d3f1328c317a2d66f8e3cee700d11afd7a739d Mon Sep 17 00:00:00 2001 From: noise Date: Sun, 18 Jan 2026 22:25:54 +0800 Subject: [PATCH 26/31] docs(cn): update api/advanced/test-case.md --- api/advanced/test-case.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/advanced/test-case.md b/api/advanced/test-case.md index 46af190a..8879e824 100644 --- a/api/advanced/test-case.md +++ b/api/advanced/test-case.md @@ -272,7 +272,7 @@ interface TestDiagnostic { function annotations(): ReadonlyArray ``` -在测试执行期间通过 [`task.annotate`](/guide/test-context#annotate) API 添加的[测试注释](/guide/test-annotations)。 +通过 [`task.annotate`](/guide/test-context#annotate) API,在测试执行过程中添加的 [测试注释](/guide/test-annotations)。 ## artifacts 4.0.11 {#artifacts} @@ -280,4 +280,4 @@ function annotations(): ReadonlyArray function artifacts(): ReadonlyArray ``` -在测试执行期间通过 `recordArtifact` API 记录的[测试工件](/api/advanced/artifacts)。 +通过 `recordArtifact` API,在测试执行过程中记录的 [测试产物](/api/advanced/artifacts)。 From 03c27dc7adb0d71dd91f6f79fa6e49087d4cc49f Mon Sep 17 00:00:00 2001 From: noise Date: Sun, 18 Jan 2026 22:30:19 +0800 Subject: [PATCH 27/31] docs(cn): update config/onstacktrace.md --- config/onstacktrace.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/onstacktrace.md b/config/onstacktrace.md index 16337288..cdc5a994 100644 --- a/config/onstacktrace.md +++ b/config/onstacktrace.md @@ -7,12 +7,12 @@ outline: deep - **类型**: `(error: Error, frame: ParsedStack) => boolean | void` -在处理错误时,对每个堆栈跟踪的每一帧应用过滤函数。这不适用于 [`printConsoleTrace`](/config/printconsoletrace#printconsoletrace) 打印的堆栈跟踪。第一个参数 `error` 是一个 `TestError`。 +在处理错误时,对每个堆栈跟踪的每一帧应用过滤函数。此功能不适用于 [`printConsoleTrace`](/config/printconsoletrace#printconsoletrace) 打印的堆栈跟踪。第一个参数 `error` 是一个 `TestError` 类型。 可用于过滤掉来自第三方库的堆栈跟踪帧。 ::: tip -堆栈跟踪的总大小通常也受到 V8 的 [`Error.stackTraceLimit`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stackTraceLimit) 数字的限制。你可以在测试设置函数中将其设置为较高的值,以防止堆栈被截断。 +堆栈跟踪的总大小通常也受到 V8 的 [`Error.stackTraceLimit`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stackTraceLimit) 数值限制。你可以在测试设置函数中将其设为较大值,以防止堆栈被截断。 ::: ```ts @@ -22,12 +22,12 @@ import { defineConfig } from 'vitest/config' export default defineConfig({ test: { onStackTrace(error: TestError, { file }: ParsedStack): boolean | void { - // 如果我们遇到 ReferenceError,显示整个堆栈。 + // 如果遇到 ReferenceError,则显示完整堆栈 if (error.name === 'ReferenceError') { return } - // 拒绝所有来自第三方库的帧。 + // 拒绝所有来自第三方库的帧 if (file.includes('node_modules')) { return false } From 4e12a2fd1ef6ff50e4316fbd2628d24b306f7866 Mon Sep 17 00:00:00 2001 From: noise Date: Sun, 18 Jan 2026 23:27:08 +0800 Subject: [PATCH 28/31] docs(cn): update guide/browser/visual-regression-testing.md --- guide/browser/visual-regression-testing.md | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/guide/browser/visual-regression-testing.md b/guide/browser/visual-regression-testing.md index 7138a4b4..68582d59 100644 --- a/guide/browser/visual-regression-testing.md +++ b/guide/browser/visual-regression-testing.md @@ -29,7 +29,7 @@ Vitest 原生支持可视化回归测试。它会自动截取 UI 组件或页面 - GPU 驱动与硬件加速 - 是否使用无头模式 - 浏览器版本与设置 -- ……甚至偶发的系统差异 +- 甚至偶发的系统差异... 因此,Vitest 会在截图文件名中添加浏览器和平台信息(如 `button-chromium-darwin.png`),避免不同环境的截图互相覆盖。 @@ -103,21 +103,21 @@ $ vitest --update ## 可视化测试的工作原理 {#how-visual-tests-work} -可视化回归测试需要稳定的截图进行比较。但页面不会立即稳定,因为图像需要加载、动画需要完成、字体需要渲染、布局需要稳定。 +可视化回归测试需要稳定的截图进行比较。但页面不会立即稳定,图片加载、动画完成、字体渲染和布局稳定都需要时间。 -Vitest 通过"稳定截图检测"自动处理这一问题: +Vitest 通过 “稳定截图检测” 机制自动处理这一问题: -1. Vitest 拍摄第一张截图(或使用参考截图,如果可用)作为基线 -1. 它拍摄另一张截图并与基线进行比较 - - 如果截图匹配,页面是稳定的,测试继续 - - 如果它们不同,Vitest 使用最新的截图作为基线并重复 -1. 这会持续进行,直到达到稳定性或超时 +1. Vitest 首先拍摄初始截图(或使用现有参考截图)作为基准 +2. 再次拍摄截图并与基准比对 + - 如果截图一致,判定页面已稳定并继续测试 + - 如果存在差异,则将最新截图设为新基准并重复流程 +3. 这会持续进行,直到达到稳定性或超时 -这确保了瞬态视觉变化(如加载旋转器或动画)不会导致错误的失败。但是,如果某些内容永远不会停止动画,你将达到超时,因此请考虑[在测试期间禁用动画](#disable-animations)。 +此机制确保临时性视觉变化(如加载动画)不会引发误报。但对于持续动画元素,系统会因超时而终止,建议测试期间 [禁用动画](#disable-animations)。 -如果在重试后(一次或多次)捕获到稳定的截图并且存在参考截图,Vitest 会使用 `createDiff: true` 与参考进行最终比较。如果它们不匹配,这将生成差异图像。 +当经过重试(一次或多次)获得稳定截图且存在参考截图时,Vitest 会使用 `createDiff: true` 参数执行最终比对。若结果不匹配,将生成差异图像。 -在稳定性检测期间,Vitest 使用 `createDiff: false` 调用比较器,因为它只需要知道截图是否匹配。这使检测过程保持快速。 +在稳定性检测阶段,Vitest 调用比对器时使用 `createDiff: false` 参数,因此仅需判断截图是否匹配。这种优化使检测过程保持高效。 ## 配置可视化测试 {#configuring-visual-tests} @@ -135,9 +135,9 @@ export default defineConfig({ toMatchScreenshot: { comparatorName: 'pixelmatch', comparatorOptions: { - // 0-1,颜色可以有多大差异? + // 0-1,表示允许的颜色差异阈值 threshold: 0.2, - // 1% 的像素可以不同 + // 允许 1% 的像素存在差异 allowedMismatchedPixelRatio: 0.01, }, }, @@ -155,7 +155,7 @@ export default defineConfig({ await expect(element).toMatchScreenshot('button-hover', { comparatorName: 'pixelmatch', comparatorOptions: { - // 对文本密集型元素进行更宽松的比较 + // 对文字密集型元素采用更宽松的比对标准 allowedMismatchedPixelRatio: 0.1, }, }) @@ -634,16 +634,16 @@ export default defineConfig({ 该服务会提供两个关键环境变量: - `PLAYWRIGHT_SERVICE_URL`:指示 Playwright 连接的服务器地址 -- `PLAYWRIGHT_SERVICE_ACCESS_TOKEN`:你的身份验证令牌 +- `PLAYWRIGHT_SERVICE_ACCESS_TOKEN`:你的身份认证令牌 -按照[官方指南创建 Playwright 工作区](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/quickstart-run-end-to-end-tests?tabs=playwrightcli&pivots=playwright-test-runner#create-a-workspace)。 +按照 [官方指南创建 Playwright 工作区](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/quickstart-run-end-to-end-tests?tabs=playwrightcli&pivots=playwright-test-runner#create-a-workspace)。 -创建工作区后,配置 Vitest 以使用它: +创建工作区后,配置 Vitest 使用该工作区: -1. **设置端点 URL**:按照[官方指南](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/quickstart-run-end-to-end-tests?tabs=playwrightcli&pivots=playwright-test-runner#configure-the-browser-endpoint),检索 URL 并将其设置为 `PLAYWRIGHT_SERVICE_URL` 环境变量。 -2. **启用令牌身份验证**:为你的工作区[启用访问令牌](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/how-to-manage-authentication?pivots=playwright-test-runner#enable-authentication-using-access-tokens),然后[生成令牌](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/how-to-manage-access-tokens#generate-a-workspace-access-token)并将其设置为 `PLAYWRIGHT_SERVICE_ACCESS_TOKEN` 环境变量。 +1. **设置端点 URL**:按照 [官方指南](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/quickstart-run-end-to-end-tests?tabs=playwrightcli&pivots=playwright-test-runner#configure-the-browser-endpoint),检索 URL 并将其设置为 `PLAYWRIGHT_SERVICE_URL` 环境变量。 +2. **启用令牌身份认证**:为你的工作区 [启用访问令牌](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/how-to-manage-authentication?pivots=playwright-test-runner#enable-authentication-using-access-tokens),然后 [生成令牌](https://learn.microsoft.com/en-us/azure/app-testing/playwright-workspaces/how-to-manage-access-tokens#generate-a-workspace-access-token)并将其设置为 `PLAYWRIGHT_SERVICE_ACCESS_TOKEN` 环境变量。 ::: danger 令牌务必保密! 切勿将 `PLAYWRIGHT_SERVICE_ACCESS_TOKEN` 提交到代码仓库。 From 9622f196aeca35ffb06202737056945d590d2ac8 Mon Sep 17 00:00:00 2001 From: noise Date: Sun, 18 Jan 2026 23:32:37 +0800 Subject: [PATCH 29/31] docs(cn): update guide/test-context.md --- guide/test-context.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/guide/test-context.md b/guide/test-context.md index bf1f8abf..c2bbcbd4 100644 --- a/guide/test-context.md +++ b/guide/test-context.md @@ -94,7 +94,7 @@ function annotate( ): Promise ``` -添加一个 [测试注解](/guide/test-annotations),它将由你的 [报告器](/config/#reporters) 显示。 +添加一个 [测试注释](/guide/test-annotations),它将由你的 [报告器](/config/#reporters) 显示。 ```ts test('annotations API', async ({ annotate }) => { @@ -407,14 +407,14 @@ const test = baseTest.extend({ ``` ::: warning -内置的 [`task`](#task) 测试上下文在文件作用域或工作者作用域的 fixtures 中 **不可用**。这些 fixtures 接收不同的上下文对象(文件或工作者上下文),不包括像 `task` 这样的测试特定属性。 +内置的 [`task`](#task) 测试上下文在文件作用域或工作线程作用域的 fixtures 中 **不可用**。这些 fixtures 接收的是不同的上下文对象(文件或工作线程上下文),其中不包含 `task` 等测试特定属性。 -如果你需要访问文件级元数据(如文件路径),请改用 `expect.getState().testPath`。 +如需访问文件路径等文件级元数据,请改用 `expect.getState().testPath`。 ::: -`worker` 作用域将为每个工作线程运行一次夹具。运行的工作线程数量取决于各种因素。默认情况下,每个文件在单独的工作线程中运行,因此 `file` 和 `worker` 作用域的工作方式相同。 +`worker` 作用域将为每个工作线程运行一次 fixtures。运行的工作线程数量取决于多种因素。默认情况下,每个文件在独立的工作线程中运行,因此 `file` 和 `worker` 作用域的行为方式相同。 -但是,如果你禁用 [隔离](/config/#isolate),那么工作线程数量将受到 [`maxWorkers`](/config/#maxworkers) 配置的限制。 +但是,如果你禁用 [隔离](/config/#isolate) 配置,则工作线程数量将受到 [`maxWorkers`](/config/#maxworkers) 配置限制。 请注意,在 `vmThreads` 或 `vmForks` 中运行测试时,指定 `scope: 'worker'` 的工作方式与 `scope: 'file'` 相同。这个限制存在是因为每个测试文件都有自己的 VM 上下文,所以如果 Vitest 只初始化一次,一个上下文可能会泄漏到另一个上下文中,并创建许多引用不一致的问题(例如,同一个类的实例会引用不同的构造函数)。 From 4c42b60f6709acf0ceccc54de25f3fecb1abb8b9 Mon Sep 17 00:00:00 2001 From: noise Date: Mon, 19 Jan 2026 00:42:49 +0800 Subject: [PATCH 30/31] docs(cn): update guide/open-telemetry.md --- guide/open-telemetry.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/guide/open-telemetry.md b/guide/open-telemetry.md index 2f6c4e53..905ad5a5 100644 --- a/guide/open-telemetry.md +++ b/guide/open-telemetry.md @@ -8,21 +8,21 @@ [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/opentelemetry) ::: -[OpenTelemetry](https://opentelemetry.io/) 追踪可以成为调试测试中应用程序性能和行为的有用工具。 +[OpenTelemetry](https://opentelemetry.io/) 跟踪是一个非常实用的工具,能帮助我们在测试过程中更轻松地了解和调试应用程序的性能与行为表现。 -如果启用,Vitest 集成会生成作用域限定在测试工作者的跨度(spans)。 +启用后,Vitest 集成会生成与测试工作线程作用域绑定的追踪区间 (spans)。 ::: warning -OpenTelemetry 初始化会增加每个测试的启动时间,除非 Vitest 在没有 [隔离](/config/isolate) 的情况下运行。你可以在 `vitest.worker.start` 内部看到它作为 `vitest.runtime.traces` 跨度。 +除非 Vitest 在关闭 [隔离](/config/isolate) 模式下运行,否则 OpenTelemetry 初始化会延长每个测试的启动时间。你可在 `vitest.worker.start` 中查看名为 `vitest.runtime.traces` 的追踪跨度。 ::: -要在 Vitest 中开始使用 OpenTelemetry,请通过 [`experimental.openTelemetry.sdkPath`](/config/experimental#experimental-opentelemetry) 指定 SDK 模块路径,并将 `experimental.openTelemetry.enabled` 设置为 `true`。Vitest 将自动检测整个进程和每个单独的测试工作者。 +要在 Vitest 中使用 OpenTelemetry,需通过 [`experimental.openTelemetry.sdkPath`](/config/experimental#experimental-opentelemetry) 指定 SDK 模块路径,并将 `experimental.openTelemetry.enabled` 设为 `true`。Vitest 将自动为整个进程及每个独立测试工作线程添加监测。 -确保将 SDK 作为默认导出导出,以便 Vitest 可以在进程关闭之前刷新网络请求。请注意,Vitest 不会自动调用 `start`。 +确保将 SDK 作为默认导出,以便 Vitest 在进程关闭前能刷新网络请求。注意 Vitest 不会自动调用 `start` 方法。 ## 快速开始 {#quickstart} -在预览应用程序追踪之前,请安装所需的包并在配置中指定检测文件的路径。 +在预览应用程序追踪数据前,请先安装所需依赖包并在配置中指定检测文件路径。 ```shell npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-proto @@ -60,16 +60,16 @@ export default defineConfig({ ::: ::: danger 假计时器 -如果你正在使用假计时器(fake timers),在测试结束前重置它们很重要,否则追踪可能无法正确跟踪。 +如果你正在使用假计时器(fake timers),务必在测试结束前重置它们,否则可能导致追踪数据记录异常。 ::: -Vitest 不会处理 `sdkPath` 模块,因此 SDK 能够在你的 Node.js 环境中导入很重要。理想情况下,为此文件使用 `.js` 扩展名。使用其他扩展名会减慢测试速度,并可能需要提供额外的 Node.js 参数。 +Vitest 不会处理 `sdkPath` 模块的转译,因此该 SDK 必须能在 Node.js 环境中直接导入。建议使用 `.js` 扩展名的文件,其他扩展名会降低测试速度并可能需要额外配置 Node.js 参数。 -如果你想提供 TypeScript 文件,请确保熟悉 Node.js 文档中的 [TypeScript](https://nodejs.org/api/typescript.html#type-stripping) 页面。 +如果你想使用 TypeScript 文件,请提前阅读 Node.js 文档中的 [TypeScript](https://nodejs.org/api/typescript.html#type-stripping) 章节了解类型剥离机制。 ## 自定义追踪 {#custom-traces} -你可以自己使用 OpenTelemetry API 来跟踪代码中的某些操作。自定义追踪会自动继承 Vitest OpenTelemetry 上下文: +你可以自己使用 OpenTelemetry API 来跟踪代码中的某些操作。自定义追踪会自动继承 Vitest 的 OpenTelemetry 上下文: ```ts import { trace } from '@opentelemetry/api' @@ -79,14 +79,14 @@ import { db } from './src/db' const tracer = trace.getTracer('vitest') test('db connects properly', async () => { - // 这会显示在 `vitest.test.runner.test.callback` 跨度内部 + // 该操作会显示在 `vitest.test.runner.test.callback` 跨度中 await tracer.startActiveSpan('db.connect', () => db.connect()) }) ``` ## 浏览器模式 {#browser-mode} -在[浏览器模式](/guide/browser/)下运行测试时,Vitest 会在 Node.js 和浏览器之间传播追踪上下文。Node.js 端的追踪(测试编排、浏览器驱动程序通信)无需额外配置即可使用。 +在 [浏览器模式](/guide/browser/) 下运行测试时,Vitest 会在 Node.js 和浏览器之间传播追踪上下文。Node.js 端的追踪信息(测试编排、浏览器驱动程序通信)无需额外配置即可获取。 要从浏览器运行时捕获追踪,请通过 `browserSdkPath` 提供与浏览器兼容的 SDK: @@ -134,23 +134,23 @@ export default defineConfig({ ::: ::: warning 异步上下文 -与 Node.js 不同,浏览器没有自动的异步上下文传播。Vitest 在内部为测试执行处理这一点,但深度嵌套异步代码中的自定义跨度可能不会自动传播上下文。 +与 Node.js 不同,浏览器不具备自动的异步上下文传播能力。Vitest 在内部为测试执行处理这一点,但对于深度嵌套的异步代码中的自定义跨度,上下文可能不会自动传播。 ::: ## 查看追踪 {#view-traces} -要生成追踪,请像往常一样运行 Vitest。你可以在观察模式或运行模式下运行 Vitest。Vitest 会在一切完成后手动调用 `sdk.shutdown()`,以确保追踪得到正确处理。 +生成追踪数据时,请像往常一样运行 Vitest,无论是 watch 模式还是运行模式均可。Vitest 会在所有操作完成后手动调用 `sdk.shutdown()` 以确保追踪数据得到正确处理。 -你可以使用任何支持 OpenTelemetry API 的开源或商业产品来查看追踪。如果你之前没有使用过 OpenTelemetry,我们建议从 [Jaeger](https://www.jaegertracing.io/docs/2.11/getting-started/#all-in-one) 开始,因为它真的很容易设置。 +你可以使用任何支持 OpenTelemetry API 的开源或商业产品来查看追踪。。如果是初次接触 OpenTelemetry,我们推荐从 [Jaeger](https://www.jaegertracing.io/docs/2.11/getting-started/#all-in-one) 开始,因为它真的很容易设置。 ## `@opentelemetry/api` {#opentelemetry-api} -Vitest 将 `@opentelemetry/api` 声明为可选的对等依赖项,它在内部使用它来生成跨度。当未启用追踪收集时,Vitest 不会尝试使用此依赖项。 +Vitest 将 `@opentelemetry/api` 声明为可选的对等依赖项,内部使用该库生成跨度。当未启用追踪收集功能时,Vitest 不会尝试使用此依赖项。 -在配置 Vitest 使用 OpenTelemetry 时,你通常会安装 `@opentelemetry/sdk-node`,它包含 `@opentelemetry/api` 作为传递依赖项,从而满足 Vitest 的对等依赖项要求。如果你遇到指示找不到 `@opentelemetry/api` 的错误,这通常意味着未启用追踪收集。如果在正确配置后错误仍然存在,你可能需要显式安装 `@opentelemetry/api`。 +在配置 Vitest 使用 OpenTelemetry 时,你通常会安装 `@opentelemetry/sdk-node`,它包含 `@opentelemetry/api` 作为传递依赖项,从而满足 Vitest 的对等依赖项要求。如果出现 `@opentelemetry/api` 未找到的错误,通常意味着未启用追踪收集功能。若正确配置后问题仍然存在,可能需要显式安装 `@opentelemetry/api`。 ## 进程间上下文传播 {#inter-process-context-propagation} -Vitest 支持通过 `TRACEPARENT` 和 `TRACESTATE` 环境变量从父进程自动传播上下文,如 [OpenTelemetry 规范](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/env-carriers.md)中所定义。这在将 Vitest 作为更大的分布式追踪系统的一部分运行时特别有用(例如,具有 OpenTelemetry 检测的 CI/CD 管道)。 +Vitest 支持通过 `TRACEPARENT` 和 `TRACESTATE` 环境变量从父进程的自动上下文传播,其遵循 [OpenTelemetry 规范](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/env-carriers.md) 中所定义。这在将 Vitest 作为大型分布式追踪系统的一部分运行时尤为实用(例如,具有 OpenTelemetry 检测的 CI/CD 管道)。 From a17070b6803538a0adfdbeacdba86b7f75ab4857 Mon Sep 17 00:00:00 2001 From: noise Date: Mon, 19 Jan 2026 01:53:08 +0800 Subject: [PATCH 31/31] docs(cn): update --- .vitepress/components/Advanced.vue | 4 ++-- api/advanced/test-suite.md | 2 +- api/browser/interactivity.md | 2 +- api/expect.md | 4 ++-- config/browser.md | 4 ++-- guide/browser/component-testing.md | 10 +++++----- guide/browser/visual-regression-testing.md | 4 ++-- guide/features.md | 3 --- guide/test-context.md | 2 +- 9 files changed, 16 insertions(+), 19 deletions(-) diff --git a/.vitepress/components/Advanced.vue b/.vitepress/components/Advanced.vue index de842162..58ef886d 100644 --- a/.vitepress/components/Advanced.vue +++ b/.vitepress/components/Advanced.vue @@ -1,6 +1,6 @@ diff --git a/api/advanced/test-suite.md b/api/advanced/test-suite.md index 5af02c34..f4ef8ead 100644 --- a/api/advanced/test-suite.md +++ b/api/advanced/test-suite.md @@ -200,7 +200,7 @@ function meta(): TaskMeta ``` 在执行或收集过程中附加到套件的自定义[元数据](/api/advanced/metadata)。在测试运行期间,可以通过向 `task.meta` 对象分配属性来附加 meta: -```ts {7,12} +```ts {6,11} import { describe, test, TestRunner } from 'vitest' describe('the validation works correctly', () => { diff --git a/api/browser/interactivity.md b/api/browser/interactivity.md index f8ca42b1..325573c1 100644 --- a/api/browser/interactivity.md +++ b/api/browser/interactivity.md @@ -2,7 +2,7 @@ title: 交互性 API | 浏览器模式 --- -# 交互性 API +# 交互性 API {#interactivity-api} Vitest 使用 [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/) 或 [webdriver](https://www.w3.org/TR/webdriver/) 实现了 [`@testing-library/user-event`](https://testing-library.com/docs/user-event/intro) 库的子集 API,而不是伪造事件,这使得浏览器行为更加可靠和一致,符合用户与页面交互的方式。 diff --git a/api/expect.md b/api/expect.md index 0026be13..e9994952 100644 --- a/api/expect.md +++ b/api/expect.md @@ -191,7 +191,7 @@ test('stocks are the same', () => { - **类型:** `(value: number, numDigits?: number) => Awaitable` -使用 `toBeCloseTo` 来比较浮点数。可选的 `numDigits` 参数用于限制小数点_后_要检查的位数。`numDigits` 的默认值为 2。例如: +使用 `toBeCloseTo` 来比较浮点数。可选的 `numDigits` 参数用于限制小数点 _后_ 要检查的位数。`numDigits` 的默认值为 2。例如: ```ts import { expect, test } from 'vitest' @@ -771,7 +771,7 @@ test('invoice has john personal details', () => { expect(johnInvoice).toMatchObject(johnDetails) }) -test('元素数量必须完全匹配', () => { +test('the number of elements must match exactly', () => { // 断言对象数组匹配 expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([ { foo: 'bar' }, diff --git a/config/browser.md b/config/browser.md index ca92645c..061ce57b 100644 --- a/config/browser.md +++ b/config/browser.md @@ -94,7 +94,7 @@ export default defineConfig({ - [`browser.screenshotFailures`](#browser-screenshotfailures) - [`browser.provider`](#browser-provider) -在底层,Vitest 将这些实例转换为共享单个 Vite 服务器的单独[测试项目](/api/advanced/test-project),以获得更好的缓存性能。 +在底层,Vitest 将这些实例转换为共享单个 Vite 服务器的单独 [测试项目](/api/advanced/test-project),以获得更好的缓存性能。 ## browser.headless @@ -192,7 +192,7 @@ export default defineConfig({ ### 自定义提供者 高级 {#custom-provider-advanced} -::: danger ADVANCED API +::: danger 高级 API 自定义提供者 API 高度实验性,并且可能在补丁版本之间发生变化。如果你只需要在浏览器中运行测试,请改用 [`browser.instances`](#browser-instances) 选项。 ::: diff --git a/guide/browser/component-testing.md b/guide/browser/component-testing.md index ec9bbb27..c0034e3d 100644 --- a/guide/browser/component-testing.md +++ b/guide/browser/component-testing.md @@ -39,7 +39,7 @@ Vitest中的组件测试使用**浏览器模式**在真实浏览器环境中运 本指南专门介绍使用Vitest功能的**组件测试模式和最佳实践**。虽然许多示例使用浏览器模式(因为这是推荐的方法),但这里的重点是组件特定的测试策略,而不是浏览器配置细节。 -有关详细的浏览器设置、配置选项和高级浏览器功能,请参阅[浏览器模式文档](/guide/browser/)。 +有关详细的浏览器设置、配置选项和高级浏览器功能,请参阅 [浏览器模式文档](/guide/browser/)。 ## 什么是好的组件测试 {#what-makes-a-good-component-test} @@ -123,7 +123,7 @@ test('ProductList filters and displays products correctly', async () => { ## Testing Library 集成 {#testing-library-integration} -虽然Vitest为流行的框架提供了官方包([`vitest-browser-vue`](https://www.npmjs.com/package/vitest-browser-vue)、[`vitest-browser-react`](https://www.npmjs.com/package/vitest-browser-react)、[`vitest-browser-svelte`](https://www.npmjs.com/package/vitest-browser-svelte)),但你也可以为尚未得到官方支持的框架集成[Testing Library](https://testing-library.com/)。 +虽然Vitest为流行的框架提供了官方包([`vitest-browser-vue`](https://www.npmjs.com/package/vitest-browser-vue)、[`vitest-browser-react`](https://www.npmjs.com/package/vitest-browser-react)、[`vitest-browser-svelte`](https://www.npmjs.com/package/vitest-browser-svelte)),但你也可以为尚未得到官方支持的框架集成 [Testing Library](https://testing-library.com/)。 ### 何时使用 Testing Library {#when-to-use-testing-library} @@ -181,7 +181,7 @@ test('Solid component handles user interaction', async () => { 确保测试在真实浏览器环境中运行以获得最准确的测试结果。浏览器模式提供准确的CSS渲染、真实的浏览器API和正确的事件处理。 ### 2. 测试用户交互 {#_2-test-user-interactions} -使用Vitest的[交互API](/api/browser/interactivity)模拟真实用户行为。使用`page.getByRole()`和`userEvent`方法,如我们的 [高级测试模式](#advanced-testing-patterns) 所示: +使用Vitest的 [交互API](/api/browser/interactivity) 模拟真实用户行为。使用`page.getByRole()`和`userEvent`方法,如我们的 [高级测试模式](#advanced-testing-patterns) 所示: ```tsx // Good: Test actual user interactions @@ -193,7 +193,7 @@ await page.getByLabelText(/email/i).fill('user@example.com') ``` ### 3. 测试可访问性 {#_3-test-accessibility} -通过测试键盘导航、焦点管理和ARIA属性,确保组件对所有用户都能正常工作。请查看我们的[测试可访问性](#testing-accessibility)示例了解实用模式: +通过测试键盘导航、焦点管理和ARIA属性,确保组件对所有用户都能正常工作。请查看我们的 [测试可访问性](#testing-accessibility) 示例了解实用模式: ```tsx // Test keyboard navigation @@ -205,7 +205,7 @@ await expect.element(modal).toHaveAttribute('aria-modal', 'true') ``` ### 4. 模拟外部依赖 {#_4-mock-external-dependencies} -通过模拟API和外部服务,将测试重点放在组件逻辑上。这使得测试更快、更可靠。请查看我们的[隔离策略](#isolation-strategy)获取示例: +通过模拟API和外部服务,将测试重点放在组件逻辑上。这使得测试更快、更可靠。请查看我们的 [隔离策略](#isolation-strategy) 获取示例: ```tsx // For API requests, we recommend using MSW (Mock Service Worker) diff --git a/guide/browser/visual-regression-testing.md b/guide/browser/visual-regression-testing.md index 68582d59..bdf31633 100644 --- a/guide/browser/visual-regression-testing.md +++ b/guide/browser/visual-regression-testing.md @@ -701,10 +701,10 @@ env: 如果你的团队已经深度依赖 GitHub 生态,那么 **GitHub Actions** 几乎是无可替代的选择——对开源项目免费、 支持任意浏览器服务商、并且可完全掌控执行流程。 -缺点在于:当有人在本地生成的截图与 CI 环境的基准不一致时,就会出现那句熟悉的“在我机器上没问题”。 +缺点在于:当有人在本地生成的截图与 CI 环境的基准不一致时,就会出现那句熟悉的 “在我机器上没问题”。 如果团队需要在本地执行视觉回归测试,那么云服务或许更适合。 这种方式特别适合有设计师参与审核,或开发者希望在推送代码前发现并修复问题的团队, -能够跳过“推送—等待—检查—修改—再推送”的繁琐循环。 +能够跳过 “推送—等待—检查—修改—再推送” 的繁琐循环。 如果依然犹豫,不妨先从 GitHub Actions 开始;等到本地测试成为痛点时,再引入云服务也不迟。 diff --git a/guide/features.md b/guide/features.md index ed020709..284a0fa0 100644 --- a/guide/features.md +++ b/guide/features.md @@ -39,9 +39,6 @@ $ vitest ## 多线程 {#threads} -默认情况下,Vitest 使用 [`node:child_process`](https://nodejs.org/api/child_process.html) 在[多个进程](/guide/parallelism)中运行测试文件,允许测试同时运行。如果你想进一步加快测试套件的速度,可以考虑启用 `--pool=threads` 来使用 [`node:worker_threads`](https://nodejs.org/api/worker_threads.html) 运行测试(请注意,某些包可能无法在此设置下工作)。 -要在单个线程或进程中运行测试,请参阅 [`fileParallelism`](/config/#fileParallelism)。 - 默认情况下,Vitest 会通过 [`node:child_process`](https://nodejs.org/api/child_process.html) 在 [多个进程](/guide/parallelism) 中运行测试文件,实现测试的并行执行。如需进一步提升测试速度,可考虑启用 `--pool=threads` 参数改用 [`node:worker_threads`](https://nodejs.org/api/worker_threads.html) 运行测试(但需注意某些依赖包可能不兼容此模式)。若需在单线程/进程中运行测试,请参阅 [`fileParallelism`](/config/#fileParallelism) 配置项。 Vitest 还隔离了每个测试文件的运行环境,因此一个文件中的运行环境改变不会影响其他文件。可以通过将 `--no-isolate` 传递给 CLI 来禁用隔离(以正确性换取运行性能)。 diff --git a/guide/test-context.md b/guide/test-context.md index c2bbcbd4..5b1affaa 100644 --- a/guide/test-context.md +++ b/guide/test-context.md @@ -439,7 +439,7 @@ test('types are defined correctly', ({ todos, archive }) => { }) ``` -::: info Type Inferring +::: info 类型推断 请注意,Vitest 不支持在调用 `use` 函数时推断类型。在调用 `test.extend` 时,最好将整个上下文类型作为泛型类型传递: ```ts