diff --git a/.vitepress/components.d.ts b/.vitepress/components.d.ts index db9aa7d6..2977c6af 100644 --- a/.vitepress/components.d.ts +++ b/.vitepress/components.d.ts @@ -8,7 +8,9 @@ export {} /* prettier-ignore */ declare module 'vue' { export interface GlobalComponents { + ArrowDown: typeof import('./components/ArrowDown.vue')['default'] BlogIndex: typeof import('./components/BlogIndex.vue')['default'] + Box: typeof import('./components/Box.vue')['default'] Contributors: typeof import('./components/Contributors.vue')['default'] CourseLink: typeof import('./components/CourseLink.vue')['default'] FeaturesList: typeof import('./components/FeaturesList.vue')['default'] diff --git a/.vitepress/components/ArrowDown.vue b/.vitepress/components/ArrowDown.vue new file mode 100644 index 00000000..3a25019b --- /dev/null +++ b/.vitepress/components/ArrowDown.vue @@ -0,0 +1,27 @@ + + + diff --git a/.vitepress/components/Box.vue b/.vitepress/components/Box.vue new file mode 100644 index 00000000..29147476 --- /dev/null +++ b/.vitepress/components/Box.vue @@ -0,0 +1,18 @@ + + + diff --git a/.vitepress/components/FeaturesList.vue b/.vitepress/components/FeaturesList.vue index 56cbafd2..59c2fb77 100644 --- a/.vitepress/components/FeaturesList.vue +++ b/.vitepress/components/FeaturesList.vue @@ -1,10 +1,29 @@ diff --git a/.vitepress/config.ts b/.vitepress/config.ts index 9d01d1b4..636cb078 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -469,8 +469,13 @@ function guide(): DefaultTheme.SidebarItem[] { link: '/guide/filtering', }, { +<<<<<<< HEAD text: '工作空间', link: '/guide/workspace', +======= + text: 'Test Projects', + link: '/guide/projects', +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 }, { text: '报告器「Reporters」', @@ -489,7 +494,15 @@ function guide(): DefaultTheme.SidebarItem[] { link: '/guide/mocking', }, { +<<<<<<< HEAD text: '类型测试', +======= + text: 'Parallelism', + link: '/guide/parallelism', + }, + { + text: 'Testing Types', +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 link: '/guide/testing-types', }, { @@ -505,7 +518,15 @@ function guide(): DefaultTheme.SidebarItem[] { link: '/guide/test-context', }, { +<<<<<<< HEAD text: '测试环境', +======= + text: 'Test Annotations', + link: '/guide/test-annotations', + }, + { + text: 'Environment', +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 link: '/guide/environment', }, { diff --git a/.vitepress/sponsors.ts b/.vitepress/sponsors.ts index b3070e42..c02c3317 100644 --- a/.vitepress/sponsors.ts +++ b/.vitepress/sponsors.ts @@ -17,9 +17,9 @@ const vitestSponsors = { img: '/nuxtlabs.svg', }, { - name: 'Stackblitz', - url: 'https://stackblitz.com', - img: '/stackblitz.svg', + name: 'Bolt', + url: 'https://bolt.new', + img: '/bolt.svg', }, { name: 'Zammad', diff --git a/advanced/api/index.md b/advanced/api/index.md index 710e7a36..62ed4fcf 100644 --- a/advanced/api/index.md +++ b/advanced/api/index.md @@ -119,7 +119,11 @@ const { vitestConfig, viteConfig } = await resolveConfig({ ::: ::: warning +<<<<<<< HEAD `resolveConfig` 不会解析 `workspace`。要解析工作区配置,Vitest 需要一个已建立的 Vite 服务器。 +======= +The `resolveConfig` doesn't resolve `projects`. To resolve projects configs, Vitest needs an established Vite server. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 另外请注意,`viteConfig.test` 不会被完全解析。如果你需要 Vitest 配置,请使用 `vitestConfig` 代替。 ::: diff --git a/advanced/api/plugin.md b/advanced/api/plugin.md index fad03683..c7a9d8d1 100644 --- a/advanced/api/plugin.md +++ b/advanced/api/plugin.md @@ -53,7 +53,11 @@ Vitest 通过 `Vite` namespace 重新导出所有仅 Vite 类型的导入,我 ``` ::: +<<<<<<< HEAD 与 [`reporter.onInit`](/advanced/api/reporters#oninit) 不同,此 hooks 在 Vitest 生命周期的早期运行,允许我们更改 `coverage` 和 `reporters` 等配置。更值得注意的变化是,如果我们的插件是在项目中定义而不是在全局配置中定义的,我们可以从 [工作区项目](/guide/workspace) 操作全局配置。 +======= +Unlike [`reporter.onInit`](/advanced/api/reporters#oninit), this hooks runs early in Vitest lifecycle allowing you to make changes to configuration like `coverage` and `reporters`. A more notable change is that you can manipulate the global config from a [test project](/guide/projects) if your plugin is defined in the project and not in the global config. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ## Context @@ -93,10 +97,10 @@ function injectTestProjects( ```ts // inject a single project with a custom alias const newProjects = await injectTestProjects({ - // you can inherit the current project config by referencing `configFile` + // you can inherit the current project config by referencing `extends` // note that you cannot have a project with the name that already exists, // so it's a good practice to define a custom name - configFile: project.vite.config.configFile, + extends: project.vite.config.configFile, test: { name: 'my-custom-alias', alias: { @@ -107,7 +111,11 @@ const newProjects = await injectTestProjects({ ``` ::: warning Projects are Filtered +<<<<<<< HEAD Vitest 在配置解析期间过滤项目,因此如果用户定义了过滤器,则注入的项目可能无法解析,除非它 [与 filter 匹配](./vitest#matchesprojectfilter)。我们可以通过 `vitest.config.project` 选项更新过滤器,以始终包含我们的工作区项目: +======= +Vitest filters projects during the config resolution, so if the user defined a filter, injected project might not be resolved unless it [matches the filter](./vitest#matchesprojectfilter). You can update the filter via the `vitest.config.project` option to always include your test project: +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```ts vitest.config.project.push('my-project-name') @@ -117,7 +125,11 @@ vitest.config.project.push('my-project-name') ::: ::: tip Referencing the Current Config +<<<<<<< HEAD 如果我们想保留用户配置,可以指定 `configFile` 属性。所有其他属性都将与用户定义的配置合并。 +======= +If you want to keep the user configuration, you can specify the `extends` property. All other properties will be merged with the user defined config. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 项目的 `configFile` 可以在 Vite 的配置中访问:`project.vite.config.configFile`。 diff --git a/advanced/api/reporters.md b/advanced/api/reporters.md index 1cacdd76..74e177be 100644 --- a/advanced/api/reporters.md +++ b/advanced/api/reporters.md @@ -15,6 +15,7 @@ Vitest 拥有自己的测试运行生命周期。这些生命周期通过报告 - [`onHookStart(beforeAll)`](#onhookstart) - [`onHookEnd(beforeAll)`](#onhookend) - [`onTestCaseReady`](#ontestcaseready) + - [`onTestAnnotate`](#ontestannotate) 3.2.0 - [`onHookStart(beforeEach)`](#onhookstart) - [`onHookEnd(beforeEach)`](#onhookend) - [`onHookStart(afterEach)`](#onhookstart) @@ -316,4 +317,21 @@ function onTestCaseResult(testCase: TestCase): Awaitable 当测试完成运行或刚刚被跳过时调用此方法。请注意,如果有 `afterEach` 钩子,这将在 `afterEach` 钩子完成后调用。 +<<<<<<< HEAD 此时,[`testCase.result()`](/advanced/api/test-case#result) 将具有非挂起状态。 +======= +At this point, [`testCase.result()`](/advanced/api/test-case#result) will have non-pending state. + +## onTestAnnotate 3.2.0 {#ontestannotate} + +```ts +function onTestAnnotate( + testCase: TestCase, + annotation: TestAnnotation, +): Awaitable +``` + +The `onTestAnnotate` hook is associated with the [`context.annotate`](/guide/test-context#annotate) method. When `annotate` is invoked, Vitest serialises it and sends the same attachment to the main thread where reporter can interact with it. + +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. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 diff --git a/advanced/api/test-module.md b/advanced/api/test-module.md index ac7a5111..babcada8 100644 --- a/advanced/api/test-module.md +++ b/advanced/api/test-module.md @@ -95,5 +95,18 @@ interface ModuleDiagnostic { * This value is only available if the test was executed with `logHeapUsage` flag. */ readonly heap: number | undefined + /** + * The time spent importing every non-externalized dependency that Vitest has processed. + */ + readonly importDurations: Record +} + +/** The time spent importing & executing a non-externalized file. */ +interface ImportDuration { + /** The time spent importing & executing the file itself, not counting all non-externalized imports that the file does. */ + selfTime: number + + /** The time spent importing & executing the file and all its imports. */ + totalTime: number } ``` diff --git a/advanced/api/test-project.md b/advanced/api/test-project.md index fece1516..d6e47b03 100644 --- a/advanced/api/test-project.md +++ b/advanced/api/test-project.md @@ -4,10 +4,15 @@ title: TestProject # TestProject 3.0.0 {#testproject} +<<<<<<< HEAD - **别名**:在 3.0.0 之前称为 `WorkspaceProject` ::: warning 本指南描述了高级的 Node.js API。如果我们只是想创建一个工作区,请遵循 [Workspace](/guide/workspace) 指南。 +======= +::: warning +This guide describes the advanced Node.js API. If you just want to define projects, follow the ["Test Projects"](/guide/projects) guide. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ::: ## name @@ -26,6 +31,7 @@ vitest.projects.map(p => p.name) === [ 'custom' ] ``` +<<<<<<< HEAD ```ts [vitest.workspace.js] export default [ './packages/server', // 有 package.json,名称为 "@pkg/server" @@ -43,11 +49,40 @@ export default [ }, }, ] +======= +```ts [vitest.config.js] +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + projects: [ + './packages/server', // has package.json with "@pkg/server" + './utils', // doesn't have a package.json file + { + // doesn't customize the name + test: { + pool: 'threads', + }, + }, + { + // customized the name + test: { + name: 'custom', + }, + }, + ], + }, +}) +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ``` ::: ::: info +<<<<<<< HEAD 如果 [根项目](/advanced/api/vitest#getroottestproject) 不是用户工作区的一部分,则不会解析其 `name`。 +======= +If the [root project](/advanced/api/vitest#getroottestproject) is not part of user projects, its `name` will not be resolved. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ::: ## vitest @@ -86,6 +121,12 @@ vitest.config === vitest.projects[0].globalConfig 这是项目的已解析测试配置。 +## hash 3.2.0 {#hash} + +The unique hash of this project. This value is consistent between the reruns. + +It is based on the root of the project and its name. Note that the root path is not consistent between different OS, so the hash will also be different. + ## vite 这是项目的 [`ViteDevServer`](https://vite.dev/guide/api-javascript#vitedevserver)。所有项目都有自己的 Vite 服务器。 @@ -279,7 +320,11 @@ dynamicExample !== staticExample // ✅ ::: ::: info +<<<<<<< HEAD 在内部,Vitest 使用此方法导入全局设置、自定义覆盖率提供者、工作区文件和自定义报告器,这意味着只要它们属于同一个 Vite 服务器,它们就共享相同的模块图。 +======= +Internally, Vitest uses this method to import global setups, custom coverage providers and custom reporters, meaning all of them share the same module graph as long as they belong to the same Vite server. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ::: ## onTestsRerun diff --git a/advanced/api/vitest.md b/advanced/api/vitest.md index 4966efbe..15b75800 100644 --- a/advanced/api/vitest.md +++ b/advanced/api/vitest.md @@ -64,7 +64,11 @@ Vitest 3 在稳定公共 API 方面迈出了一步。为了实现这一点,我 ## config +<<<<<<< HEAD 根(或全局)配置。如果启用了工作区功能,项目将引用此配置作为 `globalConfig`。 +======= +The root (or global) config. If projects are defined, they will reference this as `globalConfig`. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ::: warning 这是 Vitest 配置,它不扩展 _Vite_ 配置。它仅包含从 `test` 属性解析的值。 @@ -101,9 +105,15 @@ const testCase = vitest.state.getReportedEntity(task) // 新 API ## projects +<<<<<<< HEAD 属于用户工作区的 [测试项目](/advanced/api/test-project) 数组。如果用户未指定自定义工作区,则工作区将仅包含一个 [根项目](#getrootproject)。 Vitest 将确保工作区中始终至少有一个项目。如果用户指定了不存在的 `--project` 名称,Vitest 将抛出错误。 +======= +An array of [test projects](/advanced/api/test-project) that belong to user's projects. If the user did not specify a them, this array will only contain a [root project](#getrootproject). + +Vitest will ensure that there is always at least one project in this array. If the user specifies a non-existent `--project` name, Vitest will throw an error before this array is defined. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ## getRootProject @@ -111,7 +121,11 @@ Vitest 将确保工作区中始终至少有一个项目。如果用户指定了 function getRootProject(): TestProject ``` +<<<<<<< HEAD 返回根测试项目。根项目通常不运行任何测试,并且除非用户明确在其工作区中包含根配置,或者根本没有定义工作区,否则不会包含在 `vitest.projects` 中。 +======= +This returns the root test project. The root project generally doesn't run any tests and is not included in `vitest.projects` unless the user explicitly includes the root config in their configuration, or projects are not defined at all. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 根项目的主要目标是设置全局配置。实际上,`rootProject.config` 直接引用 `rootProject.globalConfig` 和 `vitest.config`: @@ -308,7 +322,11 @@ function runTestSpecifications( ): Promise ``` +<<<<<<< HEAD 此方法根据接收到的 [规范](/advanced/api/test-specification) 运行每个测试。第二个参数 `allTestsRun` 由覆盖率提供者用于确定是否需要在根目录中检测每个文件的覆盖率(这仅在启用了覆盖率并且 `coverage.all` 设置为 `true` 时才重要)。 +======= +This method runs every test based on the received [specifications](/advanced/api/test-specification). The second argument, `allTestsRun`, is used by the coverage provider to determine if it needs to include uncovered files in report. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ::: warning 此方法不会触发 `onWatcherRerun`、`onWatcherStart` 和 `onTestsRerun` 回调。如果我们基于文件更改重新运行测试,请考虑使用 [`rerunTestSpecifications`](#reruntestspecifications) 代替。 @@ -433,7 +451,11 @@ dynamicExample !== staticExample // ✅ ::: ::: info +<<<<<<< HEAD 在内部,Vitest 使用此方法导入全局设置、自定义覆盖率提供者、工作区文件和自定义报告器,这意味着只要它们属于同一个 Vite 服务器,它们就共享相同的模块图。 +======= +Internally, Vitest uses this method to import global setups, custom coverage providers, and custom reporters, meaning all of them share the same module graph as long as they belong to the same Vite server. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ::: ## close diff --git a/advanced/pool.md b/advanced/pool.md index a2180da1..18a239ab 100644 --- a/advanced/pool.md +++ b/advanced/pool.md @@ -31,12 +31,16 @@ export default defineConfig({ }) ``` +<<<<<<< HEAD 如果我们在不同 pools 中运行测试,可以使用 [workspace](/guide/workspace) 功能: +======= +If you need to run tests in different pools, use the [`projects`](/guide/projects) feature: +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```ts [vitest.config.ts] export default defineConfig({ test: { - workspace: [ + projects: [ { extends: true, test: { @@ -48,10 +52,13 @@ export default defineConfig({ }) ``` +<<<<<<< HEAD ::: info `workspace` 字段是在 Vitest 3 中引入的。在 [Vitest 2](https://v2.vitest.dev/) 中定义工作区,需要创建一个单独的 `vitest.workspace.ts` 文件。 ::: +======= +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ## API 在 `pool` 选项中指定的文件应该导出一个函数(可以是异步的),该函数接受 `Vitest` 接口作为其第一个选项。这个函数需要返回一个与 `ProcessPool` 接口匹配的对象: @@ -69,7 +76,11 @@ export interface ProcessPool { 这个函数只会被调用一次(除非服务器配置被更新),通常最好在这个函数内初始化测试所需的一切,并在调用 `runTests` 时重复使用它。 +<<<<<<< HEAD Vitest 在安排运行新测试时调用 `runTest`。如果 `files` 为空,将不会调用它。第一个参数是一个 [TestSpecifications](/advanced/api/test-specification) 数组。在调用 `runTests` 之前,文件将使用 [`sequencer`](/config/#sequence-sequencer) 进行排序。可能(但不太可能)会有相同的文件出现两次,但它们将始终属于不同的项目 - 这是通过 [`vitest.workspace.ts`](/guide/workspace) 配置实现的。 +======= +Vitest calls `runTest` when new tests are scheduled to run. It will not call it if `files` is empty. The first argument is an array of [TestSpecifications](/advanced/api/test-specification). Files are sorted using [`sequencer`](/config/#sequence-sequencer) before `runTests` is called. It's possible (but unlikely) to have the same file twice, but it will always have a different project - this is implemented via [`projects`](/guide/projects) configuration. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 Vitest 会等到 `runTests` 执行完毕后才结束运行(即只有在 `runTests` 解决后才会触发 [`onFinished`](/advanced/reporters))。 diff --git a/advanced/reporters.md b/advanced/reporters.md index 22ed1f47..d5725fff 100644 --- a/advanced/reporters.md +++ b/advanced/reporters.md @@ -93,7 +93,6 @@ class MyReporter implements Reporter { ### 内置报告器: -1. `BasicReporter` 1. `DefaultReporter` 1. `DotReporter` 1. `JsonReporter` diff --git a/advanced/runner.md b/advanced/runner.md index 84fb57eb..3ebda1e1 100644 --- a/advanced/runner.md +++ b/advanced/runner.md @@ -173,7 +173,11 @@ interface File extends Suite { */ filepath: string /** +<<<<<<< HEAD * 文件所属的工作区项目的名称。 +======= + * The name of the test project the file belongs to. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 */ projectName: string | undefined /** @@ -218,7 +222,11 @@ interface Test extends TaskBase { */ file: File /** +<<<<<<< HEAD * 任务是否通过调用 `t.skip()` 被跳过。 +======= + * Whether the task was skipped by calling `context.skip()`. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 */ pending?: boolean /** @@ -247,7 +255,7 @@ export interface TaskResult { * 在任务执行期间发生的错误。可能存在多个错误。 * 如果 `expect.soft()` 多次失败。 */ - errors?: ErrorWithDiff[] + errors?: TestError[] /** * 任务运行所花费的时间(以毫秒为单位)。 */ diff --git a/api/expect.md b/api/expect.md index dd671bb4..ffd09b3b 100644 --- a/api/expect.md +++ b/api/expect.md @@ -773,7 +773,11 @@ test('throws on pineapples', async () => { ## toMatchSnapshot +<<<<<<< HEAD - **类型:** `(shape?: Partial | string, message?: string) => void` +======= +- **Type:** `(shape?: Partial | string, hint?: string) => void` +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 这样可以确保一个值与最近的快照匹配。 @@ -805,7 +809,11 @@ test('matches snapshot', () => { ## toMatchInlineSnapshot +<<<<<<< HEAD - **类型:** `(shape?: Partial | string, snapshot?: string, message?: string) => void` +======= +- **Type:** `(shape?: Partial | string, snapshot?: string, hint?: string) => void` +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 这确保了一个值与最近的快照相匹配。 @@ -848,7 +856,11 @@ test('matches snapshot', () => { ## toMatchFileSnapshot {#tomatchfilesnapshot} +<<<<<<< HEAD - **类型:** `(filepath: string, message?: string) => Promise` +======= +- **Type:** `(filepath: string, hint?: string) => Promise` +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 指定文件内容与快照进行比较或更新(而非使用 `.snap` 文件)。 @@ -865,13 +877,21 @@ it('render basic', async () => { ## toThrowErrorMatchingSnapshot +<<<<<<< HEAD - **类型:** `(message?: string) => void` +======= +- **Type:** `(hint?: string) => void` +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 与 [`toMatchSnapshot`](#tomatchsnapshot) 相同,但期望的值与 [`toThrowError`](#tothrowerror) 相同。 ## toThrowErrorMatchingInlineSnapshot +<<<<<<< HEAD - **类型:** `(snapshot?: string, message?: string) => void` +======= +- **Type:** `(snapshot?: string, hint?: string) => void` +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 与 [`toMatchInlineSnapshot`](#tomatchinlinesnapshot) 类似,但期望的值与 [`toThrowError`](#tothrowerror) 相同。 diff --git a/api/index.md b/api/index.md index c413096a..3496cf1d 100644 --- a/api/index.md +++ b/api/index.md @@ -179,7 +179,11 @@ test('skipped test', (context) => { }) ``` +<<<<<<< HEAD 自 Vitest 3.1 起,如果条件未知,我们可以将其作为第一个参数提供给 `skip` 方法: +======= +Since Vitest 3.1, if the condition is unknown, you can provide it to the `skip` method as the first arguments: +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```ts import { assert, test } from 'vitest' @@ -498,6 +502,7 @@ Vitest 使用 chai `format` 方法处理 `$values`。如果数值太短,可以 - **Alias:** `it.for` +<<<<<<< HEAD 作为 `test.each` 的替代,提供 [`TestContext`](/guide/test-context)。 与 `test.each` 的区别在于如何在参数中提供数组情况。 @@ -505,6 +510,15 @@ Vitest 使用 chai `format` 方法处理 `$values`。如果数值太短,可以 ```ts // `each` 展开数组用例 +======= +Alternative to `test.each` to provide [`TestContext`](/guide/test-context). + +The difference from `test.each` lies in how arrays are provided in the arguments. +Non-array arguments to `test.for` (including template string usage) work exactly the same as for `test.each`. + +```ts +// `each` spreads arrays +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 test.each([ [1, 1, 2], [1, 2, 3], @@ -514,7 +528,11 @@ test.each([ expect(a + b).toBe(expected) }) +<<<<<<< HEAD // `for` 不会展开数组用例 +======= +// `for` doesn't spread arrays (notice the square brackets around the arguments) +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 test.for([ [1, 1, 2], [1, 2, 3], @@ -525,7 +543,11 @@ test.for([ }) ``` +<<<<<<< HEAD 第二个参数是 [`TestContext`](/guide/test-context),可用于并发快照等 +======= +The 2nd argument is [`TestContext`](/guide/test-context) and can be used for concurrent snapshots, for example: +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```ts test.concurrent.for([ @@ -541,9 +563,15 @@ test.concurrent.for([ - **类型:** `(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void` +<<<<<<< HEAD `bench` 定义了一个基准。在 Vitest 术语中,基准是定义一系列操作的函数。Vitest 会多次运行该函数,以显示不同的性能结果。 Vitest 使用了 [`tinybench`](https://github.com/tinylibs/tinybench)库,继承其所有可用作第三个参数的选项。 +======= +`bench` defines a benchmark. In Vitest terms, benchmark is a function that defines a series of operations. Vitest runs this function multiple times to display different performance results. + +Vitest uses the [`tinybench`](https://github.com/tinylibs/tinybench) library under the hood, inheriting all its options that can be used as a third argument. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```ts import { bench } from 'vitest' @@ -1199,7 +1227,11 @@ describe.for([ import { beforeEach } from 'vitest' beforeEach(async () => { +<<<<<<< HEAD // 在每个测试运行之前清除模拟并添加一些测试数据。 +======= + // Clear mocks and add some testing data before each test run +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 await stopMocking() await addUser({ name: 'John' }) }) @@ -1359,6 +1391,7 @@ test('performs an organization query', async () => { ``` ::: tip +<<<<<<< HEAD 此 hook 始终以相反的顺序调用,并且不受 [`sequence.hooks`](/config/#sequence-hooks) 选项的影响。 @@ -1372,6 +1405,9 @@ test('skipped dynamically', (t) => { }) ``` +======= +This hook is always called in reverse order and is not affected by [`sequence.hooks`](/config/#sequence-hooks) option. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ::: ### onTestFailed diff --git a/api/vi.md b/api/vi.md index 3196a523..928b2d95 100644 --- a/api/vi.md +++ b/api/vi.md @@ -385,6 +385,33 @@ expect(res).toBe(5) expect(getApples).toHaveNthReturnedWith(2, 5) ``` +### vi.mockObject 3.2.0 + +- **Type:** `(value: T) => MaybeMockedDeep` + +Deeply mocks properties and methods of a given object in the same way as `vi.mock()` mocks module exports. See [automocking](/guide/mocking.html#automocking-algorithm) for the detail. + +```ts +const original = { + simple: () => 'value', + nested: { + method: () => 'real' + }, + prop: 'foo', +} + +const mocked = vi.mockObject(original) +expect(mocked.simple()).toBe(undefined) +expect(mocked.nested.method()).toBe(undefined) +expect(mocked.prop).toBe('foo') + +mocked.simple.mockReturnValue('mocked') +mocked.nested.method.mockReturnValue('mocked nested') + +expect(mocked.simple()).toBe('mocked') +expect(mocked.nested.method()).toBe('mocked nested') +``` + ### vi.isMockFunction - **类型:** `(fn: Function) => boolean` @@ -428,7 +455,24 @@ expect(spy).toHaveReturnedWith(1) ``` ::: tip +<<<<<<< HEAD 你可以在 [`afterEach`](/api/#aftereach)(或启用 [`test.restoreMocks`](/config/#restoreMocks) )中调用 [`vi.restoreAllMocks`](#vi-restoreallmocks) ,将所有方法还原为原始实现。这将还原原始的 [object descriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) ,因此无法更改方法的实现: +======= +In environments that support [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management), you can use `using` instead of `const` to automatically call `mockRestore` on any mocked function when the containing block is exited. This is especially useful for spied methods: + +```ts +it('calls console.log', () => { + using spy = vi.spyOn(console, 'log').mockImplementation(() => {}) + debug('message') + expect(spy).toHaveBeenCalled() +}) +// console.log is restored here +``` +::: + +::: tip +You can call [`vi.restoreAllMocks`](#vi-restoreallmocks) inside [`afterEach`](/api/#aftereach) (or enable [`test.restoreMocks`](/config/#restoreMocks)) to restore all methods to their original implementations. This will restore the original [object descriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty), so you won't be able to change method's implementation: +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```ts const cart = { diff --git a/blog/vitest-3-2.md b/blog/vitest-3-2.md new file mode 100644 index 00000000..772e8239 --- /dev/null +++ b/blog/vitest-3-2.md @@ -0,0 +1,327 @@ +--- +title: Vitest 3.2 is out! +author: + name: The Vitest Team +date: 2025-06-02 +sidebar: false +head: + - - meta + - property: og:type + content: website + - - meta + - property: og:title + content: Announcing Vitest 3.2 + - - meta + - property: og:image + content: https://vitest.dev/og-vitest-3-2.png + - - meta + - property: og:url + content: https://vitest.dev/blog/vitest-3-2 + - - meta + - property: og:description + content: Vitest 3.2 Release Announcement + - - meta + - name: twitter:card + content: summary_large_image +--- + +# Vitest 3.2 is out! + +_June 2, 2025_ + +![Vitest 3.2 Announcement Cover Image](/og-vitest-3-2.png) + +Vitest 3.2 focuses on improvements to Browser Mode and TypeScript support. This release also includes some new useful methods, config options and deprecates the `workspace` config in favour of `projects`. + +## `workspace` is Deprecated + +In an effort to simplify the configuration, the team decided to deprecate the separate `vitest.workspace` file and recommend using only the `projects` option in the root config. This also simplifies how the global options are configured (because you don't need to guess how to add reporters when you have no root config). + +We also decided to deprecate the `workspace` name because it clashes with other tools like PNPM that provide monorepo support via this option. Vitest doesn't run these projects with separate `CWD` and treats them more like sub-Vitests. It also gives us more space to come up with a better solution for monorepos without breaking others. + +This option will be removed completely in a future major, replaced by `projects`. Until then, Vitest will print a warning if workspace feature is used. + + + +## Annotation API + +The new [annotation API](/guide/test-annotations) allows you to annotate any test with a custom message and attachment. These annotations are visible in the UI, HTML, junit, tap and GitHub Actions reporters. Vitest will also print related annotation in the CLI if the test fails. + + + +## Scoped Fixtures + +The `test.extend` fixtures can now specify the `scope` option: either `file` or `worker`. + +```ts +const test = baseTest.extend({ + db: [ + async ({}, use) => { + // ...setup + await use(db) + await db.close() + }, + { scope: 'worker' }, + ], +}) +``` + +The file fixture is similar to using `beforeAll` and `afterAll` at the top level of the file, but it won't be called if the fixture is not used in any test. + +The `worker` fixture is initiated once per worker, but note that by default Vitest creates one worker for every test, so you need to disable [isolation](/config/#isolate) to benefit from it. + +## Custom Project Name Colors + +You can now set a custom [color](/config/#name) when using `projects`: + +::: details Config Example +```ts{6-9,14-17} +export default defineConfig({ + test: { + projects: [ + { + test: { + name: { + label: 'unit', + color: 'red', + }, + }, + }, + { + test: { + name: { + label: 'browser', + color: 'green', + }, + browser: { + enabled: true, + provider: 'playwright', + instances: [{ browser: 'chromium' }], + }, + }, + }, + ], + }, +}) +``` +::: + + + +## Custom Browser Locators API + +Built-in locators might not be enough to express your application’s needs. Instead of falling back to CSS and losing the retry-ability protection that Vitest provides through its locator API, we now recommend extending locators using the new [`locators.extend` API](/guide/browser/locators#custom-locators). + +```ts +import { locators } from '@vitest/browser/context' + +locators.extend({ + getByCommentsCount(count: number) { + return `.comments :text("${count} comments")` + }, +}) +``` + +Return a Playwright [locator string](https://playwright.dev/docs/other-locators) to construct a new locator. Note that string returned from this method will be scoped to the parent locator, if there is one. + +Now you can call `getByCommentsCount` on the `page` or any other locator directly: + +```ts +await expect.element(page.getByCommentsCount(1)).toBeVisible() +await expect.element( + page.getByRole('article', { name: 'Hello World' }) + .getByCommentsCount(1) +).toBeVisible() +``` + +If this method returns a string, then the return value will be converted into a locator, so you can keep chaining it: + +```ts +page.getByRole('article', { name: 'Hello World' }) + .getByCommentsCount(1) + .getByText('comments') +``` + +This method has access to the current locator context, if there is one (if method is called on the `page`, then context will refer to `page`), so you can chain all locator methods inside: + +```ts +import { locators } from '@vitest/browser/context' +import type { Locator } from '@vitest/browser/context' + +locators.extend({ + getByCommentsCount(this: Locator, count: number) { + return this.getByRole('comment') + .and(this.getByText(`${count} comments`)) + }, +}) +``` + +Having access to context also allows you to call regular methods of the locator to define a custom user event: + +```ts +import { locators, page } from '@vitest/browser/context' +import type { Locator } from '@vitest/browser/context' + +locators.extend({ + clickAndFill(this: Locator, text: string) { + await this.click() + await this.fill(text) + }, +}) + +await page.getByRole('textbox').clickAndFill('Hello World') +``` + +Please, refer to the [`locators.extend` API](/guide/browser/locators#custom-locators) for more information. + +## Explicit Resource Management in `vi.spyOn` and `vi.fn` + +In environments that support [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management), you can use `using` instead of `const` to automatically call `mockRestore` on any mocked function when the containing block is exited. This is especially useful for spied methods: + +```ts +it('calls console.log', () => { + using spy = vi.spyOn(console, 'log').mockImplementation(() => {}) + debug('message') + expect(spy).toHaveBeenCalled() +}) + +// console.log is restored here +``` + +## Test `signal` API + +Vitest now provides an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) object to the test body. You can use it to stop any resource that supports this Web API. + +The signal is aborted when test times out, another test fails and [`--bail` flag](/config/#bail) is set to a non-zero value, or the user presses Ctrl+C in the terminal. + +For example, you can stop a `fetch` request when tests are interrupted: + +```ts +it('stop request when test times out', async ({ signal }) => { + await fetch('/heavy-resource', { signal }) +}, 2000) +``` + +## Coverage V8 AST-aware remapping + +Vitest now uses `ast-v8-to-istanbul` package developed by one of the Vitest maintainers, [AriPerkkio](https://github.com/AriPerkkio). This brings v8 coverage report in line with istanbul, but has a better performance! Enable this feature by setting [`coverage.experimentalAstAwareRemapping`](/config/#coverage-experimentalastawareremapping) to `true`. + +We are planning to make this the default remapping mode in the next major. The old `v8-to-istanbul` will be removed completely. Feel free to join discussion at https://github.com/vitest-dev/vitest/issues/7928. + +## `watchTriggerPatterns` Option + +When you edit a file, Vitest is smart enough to rerun only tests that import this file. Unfortunately, Vitest static analysis respects only static and dynamic `import` statement. If you are reading a file or starting a separate process, Vitest will ignore changes to related files. + +With `watchTriggerPatterns` option you can configure which tests to rerun depending on the file that was changed. For example, to always rerun `mailers` tests when a template is changed, add a trigger pattern: + +```ts +export default defineConfig({ + test: { + watchTriggerPatterns: [ + { + pattern: /^src\/templates\/(.*)\.(ts|html|txt)$/, + testsToRun: (file, match) => { + return `api/tests/mailers/${match[2]}.test.ts` + }, + }, + ], + }, +}) +``` + +## The New Multi-Purpose `Matchers` Type + +Vitest now has a `Matchers` type that you can extend to add type support for all your custom matchers in one place. This type affects all these use cases: + +- `expect().to*` +- `expect.to*` +- `expect.extend({ to* })` + +For example, to have a type-safe `toBeFoo` matcher, you can write something like this: + +```ts twoslash +import { expect } from 'vitest' + +interface CustomMatchers { + toBeFoo: (arg: string) => R +} + +declare module 'vitest' { + interface Matchers extends CustomMatchers {} +} + +expect.extend({ + toBeFoo(actual, arg) { + // ^? + // ... implementation + return { + pass: true, + message: () => '', + } + } +}) + +expect('foo').toBeFoo('foo') +expect.toBeFoo('foo') +``` + +## `sequence.groupOrder` + +The new [`sequence.groupOrder`](/config/#grouporder) option controls the order in which the project runs its tests when using multiple [projects](/guide/projects). + +- Projects with the same group order number will run together, and groups are run from lowest to highest. +- If you don’t set this option, all projects run in parallel. +- If several projects use the same group order, they will run at the same time. + +::: details Example +Consider this example: + +```ts +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + projects: [ + { + test: { + name: 'slow', + sequence: { + groupOrder: 0, + }, + }, + }, + { + test: { + name: 'fast', + sequence: { + groupOrder: 0, + }, + }, + }, + { + test: { + name: 'flaky', + sequence: { + groupOrder: 1, + }, + }, + }, + ], + }, +}) +``` + +Tests in these projects will run in this order: + +``` + 0. slow | + |> running together + 0. fast | + + 1. flaky |> runs after slow and fast alone +``` +::: + +---- + +The complete list of changes is at the [Vitest 3.2 Changelog](https://github.com/vitest-dev/vitest/releases/tag/v3.2.0). diff --git a/blog/vitest-3.md b/blog/vitest-3.md index c410b555..167a4973 100644 --- a/blog/vitest-3.md +++ b/blog/vitest-3.md @@ -72,7 +72,11 @@ _January 17, 2025_ ## 内联工作区(Inline Workspace) +<<<<<<< HEAD 让我们欢呼一下,芜湖!不再需要单独的文件来定义你的[工作区](/guide/workspace) - 你可以使用 vitest.config 文件中的 `workspace` 字段指定项目数组: +======= +Rejoice! No more separate files to define your [workspace](/guide/projects) - specify an array of projects using the `workspace` field in your `vitest.config` file: +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```jsx import { defineConfig } from 'vitest/config' diff --git a/config/index.md b/config/index.md index 7e5242e1..753fc2cf 100644 --- a/config/index.md +++ b/config/index.md @@ -106,7 +106,11 @@ export default defineConfig({ 由于 Vitest 使用 Vite 的配置,我们也可以使用 [Vite](https://vitejs.dev/config/) 中的任何配置选项。例如,使用 `define` 来定义全局变量,或者使用 `resolve.alias` 来定义别名——这些选项应该在顶级定义,而不是在 `test` 属性内部。 +<<<<<<< HEAD 不支持在[工作区](/guide/workspace)项目配置中的配置选项旁边会有 标志。这意味着这些选项只能在根 Vitest 配置中设置。 +======= +Configuration options that are not supported inside a [project](/guide/projects) config have sign next to them. This means they can only be set in the root Vitest config. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ::: ### include @@ -122,9 +126,15 @@ export default defineConfig({ ### exclude +<<<<<<< HEAD - **类型:** `string[]` - **默认值:** `['**/node_modules/**', '**/dist/**', '**/cypress/**', '**/.{idea,git,cache,output,temp}/**', '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*']` - **命令行终端:** `vitest --exclude "**/excluded-file"` +======= +- **Type:** `string[]` +- **Default:** `['**/node_modules/**', '**/.git/**']` +- **CLI:** `vitest --exclude "**/excluded-file" --exclude "*/other-files/*.js"` +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 匹配排除测试文件的 glob 规则。 @@ -139,9 +149,15 @@ export default defineConfig({ ### name -- **Type:** `string` +- **Type:** `string | { label: string, color?: LabelColor }` +<<<<<<< HEAD 为测试项目或 Vitest 进程分配一个自定义名称。该名称将在 CLI 中可见,并且可以通过 Node.js API 中的 [`project.name`](/advanced/api/test-project#name) 获取。 +======= +Assign a custom name to the test project or Vitest process. The name will be visible in the CLI and UI, and available in the Node.js API via [`project.name`](/advanced/api/test-project#name). + +Color used by CLI and UI can be changed by providing an object with `color` property. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ### server {#server} @@ -466,7 +482,22 @@ export default defineConfig({ } ``` +<<<<<<< HEAD 如果你已经在项目中使用 [`unplugin-auto-import`](https://github.com/antfu/unplugin-auto-import),你也可以直接用它来自动导入这些 API。 +======= +If you have redefined your [`typeRoots`](https://www.typescriptlang.org/tsconfig/#typeRoots) to include more types in your compilation, you will have to add back the `node_modules` to make `vitest/globals` discoverable. + +```json [tsconfig.json] +{ + "compilerOptions": { + "typeRoots": ["./types", "./node_modules/@types", "./node_modules"], + "types": ["vitest/globals"] + } +} +``` + +If you are already using [`unplugin-auto-import`](https://github.com/antfu/unplugin-auto-import) in your project, you can also use it directly for auto importing those APIs. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```ts [vitest.config.js] import AutoImport from 'unplugin-auto-import/vite' @@ -577,6 +608,7 @@ jsdom 环境变量导出了等同于当前[JSDOM](https://github.com/jsdom/jsdom 这些选项被传递给当前 [`environment`](#environment) 的 `setup` 方法。 默认情况下,如果你将其用作测试环境,则只能配置 JSDOM 选项。 +<<<<<<< HEAD ### environmentMatchGlobs - **类型:** `[string, EnvironmentName][]` @@ -672,6 +704,8 @@ export default defineConfig({ }) ``` +======= +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ### update - **类型:** `boolean` @@ -692,6 +726,36 @@ In interactive environments, this is the default, unless `--run` is specified ex In CI, or when run from a non-interactive shell, "watch" mode is not the default, but can be enabled explicitly with this flag. +### watchTriggerPatterns 3.2.0 {#watchtriggerpatterns} + +- **Type:** `WatcherTriggerPattern[]` + +Vitest reruns tests based on the module graph which is populated by static and dynamic `import` statements. However, if you are reading from the file system or fetching from a proxy, then Vitest cannot detect those dependencies. + +To correctly rerun those tests, you can define a regex pattern and a function that retuns a list of test files to run. + +```ts +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + watchTriggerPatterns: [ + { + pattern: /^src\/(mailers|templates)\/(.*)\.(ts|html|txt)$/, + testsToRun: (id, match) => { + // relative to the root value + return `./api/tests/mailers/${match[2]}.test.ts` + }, + }, + ], + }, +}) +``` + +::: warning +Returned files should be either absolute or relative to the root. Note that this is a global option, and it cannot be used inside of [project](/guide/projects) configs. +::: + ### root - **类型:** `string` @@ -1271,13 +1335,17 @@ test('execute a script', async () => { ### coverage +<<<<<<< HEAD - **类型:** `CoverageC8Options | CoverageIstanbulOptions` - **默认值:** `undefined` +======= +You can use [`v8`](/guide/coverage.html#v8-provider), [`istanbul`](/guide/coverage.html#istanbul-provider) or [a custom coverage solution](/guide/coverage#custom-coverage-provider) for coverage collection. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 你可以使用点符号向 CLI 提供覆盖选项: ```sh -npx vitest --coverage.enabled --coverage.provider=istanbul --coverage.all +npx vitest --coverage.enabled --coverage.provider=istanbul ``` ::: warning @@ -1303,15 +1371,25 @@ npx vitest --coverage.enabled --coverage.provider=istanbul --coverage.all #### coverage.include +<<<<<<< HEAD - **类型:** `string[]` - **默认值:** `['**']` - **可用的测试提供者:** `'v8' | 'istanbul'` - **命令行终端:** `--coverage.include=`, `--coverage.include= --coverage.include=` 匹配包含测试覆盖率的 glob 规则 +======= +- **Type:** `string[]` +- **Default:** Files that were imported during test run +- **Available for providers:** `'v8' | 'istanbul'` +- **CLI:** `--coverage.include=`, `--coverage.include= --coverage.include=` + +List of files included in coverage as glob patterns. By default only files covered by tests are included. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 -#### coverage.extension +It is recommended to pass file extensions in the pattern. +<<<<<<< HEAD - **类型:** `string | string[]` - **默认值:** `['.js', '.cjs', '.mjs', '.ts', '.mts', '.tsx', '.jsx', '.vue', '.svelte', '.marko', '.astro']` - **可用的测试提供者:** `'v8' | 'istanbul'` @@ -1343,10 +1421,21 @@ npx vitest --coverage.enabled --coverage.provider=istanbul --coverage.all '**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}', ] ``` +======= +See [Including and excluding files from coverage report](/guide/coverage.html#including-and-excluding-files-from-coverage-report) for examples. + +#### coverage.exclude + +- **Type:** `string[]` +- **Default:** : `[]` +- **Available for providers:** `'v8' | 'istanbul'` +- **CLI:** `--coverage.exclude=`, `--coverage.exclude= --coverage.exclude=` +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 - **可用的测试提供者:** `'v8' | 'istanbul'` - **命令行终端:** `--coverage.exclude=`, `--coverage.exclude= --coverage.exclude=` +<<<<<<< HEAD 使用全局模式排除在覆盖范围之外的文件列表。 该选项覆盖所有默认选项。添加新的忽略模式时,扩展默认选项: @@ -1376,6 +1465,9 @@ Vitest 会自动将测试文件的 `include` 模式添加到 `coverage.exclude` - **命令行终端:** `--coverage.all`, `--coverage.all=false` 是否将所有文件(包括未测试的文件)包括在报告中。 +======= +See [Including and excluding files from coverage report](/guide/coverage.html#including-and-excluding-files-from-coverage-report) for examples. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 #### coverage.clean @@ -1644,6 +1736,7 @@ Sets thresholds to 100 for files matching the glob pattern. } ``` +<<<<<<< HEAD #### coverage.ignoreEmptyLines - **类型:** `boolean` @@ -1682,6 +1775,14 @@ export default defineConfig({ - **默认值:** `[]` - **可用的测试提供者:** `'istanbul'` - **命令行终端:** `--coverage.ignoreClassMethods=` +======= +#### coverage.ignoreClassMethods + +- **Type:** `string[]` +- **Default:** `[]` +- **Available for providers:** `'v8' | 'istanbul'` +- **CLI:** `--coverage.ignoreClassMethods=` +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 设置为要忽略覆盖率的类方法名称数组。参考 [istanbul 文档](https://github.com/istanbuljs/nyc#ignoring-methods) 来了解详情。 @@ -2007,7 +2108,11 @@ export default defineConfig({ ### sequence +<<<<<<< HEAD - **类型**: `{ sequencer?, shuffle?, seed?, hooks?, setupFiles? }` +======= +- **Type**: `{ sequencer?, shuffle?, seed?, hooks?, setupFiles?, groupOrder }` +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 配置测试运行顺序的选项。 @@ -2026,6 +2131,71 @@ npx vitest --sequence.shuffle --sequence.seed=1000 分片是在排序之前进行的,并且只有提供了 `--shard` 选项的情况下才会生效。 +If [`sequencer.groupOrder`](#grouporder) is specified, the sequencer will be called once for each group and pool. + +#### groupOrder 3.2.0 {#grouporder} + +- **Type:** `number` +- **Default:** `0` + +Controls the order in which this project runs its tests when using multiple [projects](/guide/projects). + +- Projects with the same group order number will run together, and groups are run from lowest to highest. +- If you don’t set this option, all projects run in parallel. +- If several projects use the same group order, they will run at the same time. + +This setting only affects the order in which projects run, not the order of tests within a project. +To control test isolation or the order of tests inside a project, use the [`isolate`](#isolate) and [`sequence.sequencer`](#sequence-sequencer) options. + +::: details Example +Consider this example: + +```ts +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + projects: [ + { + test: { + name: 'slow', + sequence: { + groupOrder: 0, + }, + }, + }, + { + test: { + name: 'fast', + sequence: { + groupOrder: 0, + }, + }, + }, + { + test: { + name: 'flaky', + sequence: { + groupOrder: 1, + }, + }, + }, + ], + }, +}) +``` + +Tests in these projects will run in this order: + +``` + 0. slow | + |> running together + 0. fast | + + 1. flaky |> runs after slow and fast alone +``` +::: + #### sequence.shuffle - **类型**: `boolean | { files?, tests? }` @@ -2170,6 +2340,13 @@ Vitest 通常使用缓存对测试进行排序,因此长时间运行的测试 自定义 tsconfig 的路径,相对于项目根目录。 +#### typecheck.spawnTimeout + +- **Type**: `number` +- **Default**: `10_000` + +Minimum time in milliseconds it takes to spawn the typechecker. + ### slowTestThreshold - **类型**: `number` @@ -2228,9 +2405,21 @@ Vitest 通常使用缓存对测试进行排序,因此长时间运行的测试 ### onConsoleLog +<<<<<<< HEAD - **类型**: `(log: string, type: 'stdout' | 'stderr') => boolean | void` 在测试自定义 `console.log` 的处理程序。如果返回 `false`,Vitest 将不会将日志打印到控制台上。 +======= +```ts +function onConsoleLog( + log: string, + type: 'stdout' | 'stderr', + entity: TestModule | TestSuite | TestCase | undefined, +): boolean | void +``` + +Custom handler for `console` methods in tests. If you return `false`, Vitest will not print the log to the console. Note that Vitest ignores all other falsy values. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 这在过滤掉来自第三方库的日志时会非常有用。 @@ -2424,14 +2613,33 @@ Limit the depth to recurse when printing nested objects ### workspace {#workspace} +<<<<<<< HEAD - **类型:** `string | TestProjectConfiguration` - **命令行终端:** `--workspace=./file.js` - **默认值:** `vitest.{workspace,projects}.{js,ts,json}` close to the config file or root 相对于[root](#root) 的 [workspace](/guide/workspace) 配置文件的路径。 +======= +::: danger DEPRECATED +This options is deprecated and will be removed in the next major. Please, use [`projects`](#projects) instead. +::: + +- **Type:** `string | TestProjectConfiguration[]` +- **CLI:** `--workspace=./file.js` +- **Default:** `vitest.{workspace,projects}.{js,ts,json}` close to the config file or root + +Path to a [workspace](/guide/projects) config file relative to [root](#root). +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 Since Vitest 3, you can also define the workspace array in the root config. If the `workspace` is defined in the config manually, Vitest will ignore the `vitest.workspace` file in the root. +### projects {#projects} + +- **Type:** `TestProjectConfiguration[]` +- **Default:** `[]` + +An array of [projects](/guide/projects). + ### isolate - **类型:** `boolean` @@ -2538,4 +2746,15 @@ export interface SnapshotEnvironment { - **类型:** `boolean` - **默认值:** `false` +<<<<<<< HEAD 调用任何`console`方法时始终打印控制台跟踪。这对于调试很有用。 +======= +Always print console traces when calling any `console` method. This is useful for debugging. + +### attachmentsDir 3.2.0 + +- **Type:** `string` +- **Default:** `'.vitest-attachments'` + +Directory path for storing attachments created by [`context.annotate`](/guide/test-context#annotate) relative to the project root. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 diff --git a/guide/browser/commands.md b/guide/browser/commands.md index 912055d7..a46b9e82 100644 --- a/guide/browser/commands.md +++ b/guide/browser/commands.md @@ -11,7 +11,11 @@ outline: deep ### 文件处理 +<<<<<<< HEAD 你可以使用 `readFile` 、`writeFile` 和 `removeFile` API 来处理浏览器测试中的文件。所有路径都是相对于测试文件解析的,即使它们是在位于另一个文件中的辅助函数中调用的。 +======= +You can use the `readFile`, `writeFile`, and `removeFile` APIs to handle files in your browser tests. Since Vitest 3.2, all paths are resolved relative to the [project](/guide/projects) root (which is `process.cwd()`, unless overriden manually). Previously, paths were resolved relative to the test file. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 默认情况下,Vitest 使用 `utf-8` 编码,但你可以使用选项覆盖它。 diff --git a/guide/browser/context.md b/guide/browser/context.md index 2958ef2f..1ff2574f 100644 --- a/guide/browser/context.md +++ b/guide/browser/context.md @@ -103,6 +103,11 @@ export const page: { `getBy*` API 在 [Locators API](/guide/browser/locators) 中有详细说明。 ::: +::: warning WARNING 3.2.0 +Note that `screenshot` will always return a base64 string if `save` is set to `false`. +The `path` is also ignored in that case. +::: + ## `cdp` `cdp` 导出返回当前的 Chrome DevTools 协议会话。它主要用于库作者在其基础上构建工具。 diff --git a/guide/browser/index.md b/guide/browser/index.md index 81d9799f..5e878ad5 100644 --- a/guide/browser/index.md +++ b/guide/browser/index.md @@ -8,7 +8,11 @@ outline: deep 此页面提供有关 Vitest API 中实验性浏览器模式功能的信息,该功能允许你在浏览器中本地运行测试,提供对窗口和文档等浏览器全局变量的访问。此功能目前正在开发中,API 未来可能会更改。 ::: tip +<<<<<<< HEAD 如果你正在寻找关于 `expect`、`vi` 或任何通用 API(如工作区或类型测试)的文档,请参阅 ["入门指南"](/guide/)。 +======= +If you are looking for documentation for `expect`, `vi` or any general API like test projects or type testing, refer to the ["Getting Started" guide](/guide/). +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ::: Vitest UI @@ -95,7 +99,11 @@ bun add -D vitest @vitest/browser webdriverio ## 配置 +<<<<<<< HEAD 要在 Vitest 配置中使用浏览器模式,我们可以使用 `--browser=name` 标志或在 Vitest 配置文件中将 `browser.enabled` 字段设置为 `true`。下面是使用浏览器字段的示例配置: +======= +To activate browser mode in your Vitest configuration, set the `browser.enabled` field to `true` in your Vitest configuration file. Here is an example configuration using the browser field: +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```ts [vitest.config.ts] import { defineConfig } from 'vitest/config' @@ -209,13 +217,18 @@ export default defineConfig({ ``` ::: +<<<<<<< HEAD 如果我们需要使用基于 Node 的运行器来运行一些测试,可以定义一个 [工作区](/guide/workspace) 文件,其中包含不同测试策略的独立配置: +======= +If you need to run some tests using Node-based runner, you can define a [`projects`](/guide/projects) option with separate configurations for different testing strategies: +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 -{#workspace-config} +{#projects-config} -```ts [vitest.workspace.ts] -import { defineWorkspace } from 'vitest/config' +```ts [vitest.config.ts] +import { defineConfig } from 'vitest/config' +<<<<<<< HEAD export default defineWorkspace([ { test: { @@ -243,10 +256,43 @@ export default defineWorkspace([ instances: [ { browser: 'chromium' }, ], +======= +export default defineConfig({ + test: { + projects: [ + { + test: { + // an example of file based convention, + // you don't have to follow it + include: [ + 'tests/unit/**/*.{test,spec}.ts', + 'tests/**/*.unit.{test,spec}.ts', + ], + name: 'unit', + environment: 'node', + }, +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 }, - }, + { + test: { + // an example of file based convention, + // you don't have to follow it + include: [ + 'tests/browser/**/*.{test,spec}.ts', + 'tests/**/*.browser.{test,spec}.ts', + ], + name: 'browser', + browser: { + enabled: true, + instances: [ + { browser: 'chromium' }, + ], + }, + }, + }, + ], }, -]) +}) ``` ## Browser Option Types @@ -320,7 +366,7 @@ Vitest 使用 [Vite dev server](https://cn.vitejs.dev/guide/#browser-support) 要使用 CLI 指定浏览器,请使用 `--browser` 标志后跟浏览器名称,如下所示: ```sh -npx vitest --browser=chrome +npx vitest --browser=chromium ``` 或者你可以使用点符号向 CLI 提供浏览器选项: @@ -329,7 +375,15 @@ npx vitest --browser=chrome npx vitest --browser.headless ``` +<<<<<<< HEAD 默认情况下,Vitest 会自动打开浏览器用户界面进行开发。我们的测试将在中间的 iframe 中运行。我们可以通过选择首选尺寸、在测试中调用 `page.viewport` 或在 [the config](/config/#browser-viewport) 中设置默认值来配置视口。 +======= +::: warning +Since Vitest 3.2, if you don't have the `browser` option in your config but specify the `--browser` flag, Vitest will fail because it can't assume that config is meant for the browser and not Node.js tests. +::: + +By default, Vitest will automatically open the browser UI for development. Your tests will run inside an iframe in the center. You can configure the viewport by selecting the preferred dimensions, calling `page.viewport` inside the test, or setting default values in [the config](/config/#browser-viewport). +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ## Headless @@ -398,7 +452,12 @@ test('properly handles form inputs', async () => { 其他框架也有社区提供的软件包: +<<<<<<< HEAD - [`vitest-browser-lit`](https://github.com/EskiMojo14/vitest-browser-lit) 用于渲染 [lit](https://lit.dev) 组件 +======= +- [`vitest-browser-lit`](https://github.com/EskiMojo14/vitest-browser-lit) to render [lit](https://lit.dev) components +- [`vitest-browser-preact`](https://github.com/JoviDeCroock/vitest-browser-preact) to render [preact](https://preactjs.com) components +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 如果你的框架没有被包含在内,请随时创建你自己的软件包——它是一个简单的封装,围绕着框架渲染器和 `page.elementLocator` API。我们会在本页面添加指向它的链接。请确保其名称以 `vitest-browser-` 开头。 @@ -488,15 +547,35 @@ test('greeting appears on click', async () => { await expect.element(greeting).toBeInTheDocument() }) ``` +```tsx [preact] +import { render } from 'vitest-browser-preact' +import { createElement } from 'preact' +import Greeting from '.Greeting' + +test('greeting appears on click', async () => { + const screen = render() + + const button = screen.getByRole('button') + await button.click() + const greeting = screen.getByText(/hello world/iu) + + await expect.element(greeting).toBeInTheDocument() +}) +``` ::: Vitest 并不支持所有开箱即用的框架,但我们可以使用外部工具来运行这些框架的测试。我们还鼓励社区创建他们自己的 `vitest-browser` 封装程序,如果我们有这样的封装程序,请随时将其添加到上述示例中。 对于不支持的框架,我们建议使用 `testing-library` 软件包: +<<<<<<< HEAD - [`@testing-library/preact`](https://testing-library.com/docs/preact-testing-library/intro) 渲染 [preact](https://preactjs.com) 组件 - [`@solidjs/testing-library`](https://testing-library.com/docs/solid-testing-library/intro) 渲染 [solid](https://www.solidjs.com) 组件 - [`@marko/testing-library`](https://testing-library.com/docs/marko-testing-library/intro) 渲染 [marko](https://markojs.com) 组件 +======= +- [`@solidjs/testing-library`](https://testing-library.com/docs/solid-testing-library/intro) to render [solid](https://www.solidjs.com) components +- [`@marko/testing-library`](https://testing-library.com/docs/marko-testing-library/intro) to render [marko](https://markojs.com) components +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 我们还可以在 [`browser-examples`](https://github.com/vitest-tests/browser-examples) 中查看更多的案例。 @@ -505,6 +584,7 @@ Vitest 并不支持所有开箱即用的框架,但我们可以使用外部工 ::: ::: code-group +<<<<<<< HEAD ```tsx [preact] // based on @testing-library/preact example // https://testing-library.com/docs/preact-testing-library/example @@ -535,8 +615,10 @@ test('shows the children when the checkbox is checked', async () => { await expect.element(screen.getByText(testMessage)).toBeInTheDocument() }) ``` +======= +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```tsx [solid] -// baed on @testing-library/solid API +// based on @testing-library/solid API // https://testing-library.com/docs/solid-testing-library/api import { render } from '@testing-library/solid' @@ -563,7 +645,7 @@ it('uses params', async () => { }) ``` ```ts [marko] -// baed on @testing-library/marko API +// based on @testing-library/marko API // https://testing-library.com/docs/marko-testing-library/api import { render, screen } from '@marko/testing-library' @@ -586,4 +668,50 @@ test('renders a message', async () => { 使用 Vitest 浏览器时,需要注意的是像 `alert` 或 `confirm` 这样的线程阻塞对话框不能在本地使用。这是因为它们阻塞了网页,这意味着 Vitest 无法继续与该页面通信,导致执行挂起。 +<<<<<<< HEAD 在这种情况下,Vitest 为这些 API 提供默认模拟和默认返回值。这确保如果用户不小心使用了同步弹出式 Web API,执行不会挂起。但是,仍然建议用户模拟这些 Web API 以获得更好的体验。在 [Mocking](/guide/mocking) 中阅读更多内容。 +======= +In such situations, Vitest provides default mocks with default returned values for these APIs. This ensures that if the user accidentally uses synchronous popup web APIs, the execution would not hang. However, it's still recommended for the user to mock these web APIs for better experience. Read more in [Mocking](/guide/mocking). + +### Spying on Module Exports + +Browser Mode uses the browser's native ESM support to serve modules. The module namespace object is sealed and can't be reconfigured, unlike in Node.js tests where Vitest can patch the Module Runner. This means you can't call `vi.spyOn` on an imported object: + +```ts +import { vi } from 'vitest' +import * as module from './module.js' + +vi.spyOn(module, 'method') // ❌ throws an error +``` + +To bypass this limitation, Vitest supports `{ spy: true }` option in `vi.mock('./module.js')`. This will automatically spy on every export in the module without replacing them with fake ones. + +```ts +import { vi } from 'vitest' +import * as module from './module.js' + +vi.mock('./module.js', { spy: true }) + +vi.mocked(module.method).mockImplementation(() => { + // ... +}) +``` + +However, the only way to mock exported _variables_ is to export a method that will change the internal value: + +::: code-group +```js [module.js] +export let MODE = 'test' +export function changeMode(newMode) { + MODE = newMode +} +``` +```js [module.test.ts] +import { expect } from 'vitest' +import { changeMode, MODE } from './module.js' + +changeMode('production') +expect(MODE).toBe('production') +``` +::: +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 diff --git a/guide/browser/interactivity-api.md b/guide/browser/interactivity-api.md index c3d79669..f8a22c2b 100644 --- a/guide/browser/interactivity-api.md +++ b/guide/browser/interactivity-api.md @@ -156,7 +156,11 @@ function fill( ): Promise ``` +<<<<<<< HEAD 为 `input/textarea/conteneditable` 字段设置值。这将在设置新值前移除输入中的任何现有文本。 +======= +Set a value to the `input`/`textarea`/`contenteditable` field. This will remove any existing text in the input before setting the new value. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```ts import { page, userEvent } from '@vitest/browser/context' @@ -263,7 +267,11 @@ function type( `type` 方法在 [`keyboard`](https://testing-library.com/docs/user-event/keyboard) API 的基础上实现了 `@testing-library/user-event` 的 [`type`](https://testing-library.com/docs/user-event/utility/#type) 工具。 +<<<<<<< HEAD 该函数允许您在 input/textarea/conteneditable 中键入字符。它支持 [user-event `keyboard` syntax](https://testing-library.com/docs/user-event/keyboard)。 +======= +This function allows you to type characters into an `input`/`textarea`/`contenteditable` element. It supports [user-event `keyboard` syntax](https://testing-library.com/docs/user-event/keyboard). +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 如果只需按下字符而无需输入,请使用 [`userEvent.keyboard`](#userevent-keyboard) API。 @@ -469,8 +477,8 @@ test('can upload a file', async () => { // or you can access it directly on the locator await input.upload(file) - // you can also use file paths relative to the test file - await userEvent.upload(input, '../fixtures/file.png') + // you can also use file paths relative to the root of the project + await userEvent.upload(input, './fixtures/file.png') }) ``` diff --git a/guide/browser/locators.md b/guide/browser/locators.md index e97a9c0d..c689df4c 100644 --- a/guide/browser/locators.md +++ b/guide/browser/locators.md @@ -702,7 +702,11 @@ await page.getByRole('img', { name: 'Rose' }).unhover() function fill(text: string, options?: UserEventFillOptions): Promise ``` +<<<<<<< HEAD 设置当前 `input`、`textarea` 或 `contenteditable` 元素的值。 +======= +Sets the value of the current `input`, `textarea` or `contenteditable` element. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ```ts import { page } from '@vitest/browser/context' @@ -769,6 +773,7 @@ await languages.selectOptions([ ### screenshot ```ts +function screenshot(options: LocatorScreenshotOptions & { save: false }): Promise function screenshot(options: LocatorScreenshotOptions & { base64: true }): Promise<{ path: string base64: string @@ -797,6 +802,11 @@ const { path, base64 } = await button.screenshot({ // bas64 - base64 encoded string of the screenshot ``` +::: warning WARNING 3.2.0 +Note that `screenshot` will always return a base64 string if `save` is set to `false`. +The `path` is also ignored in that case. +::: + ### query ```ts @@ -949,3 +959,76 @@ test('works correctly', async () => { }) ``` ::: + +## Custom Locators 3.2.0 advanced {#custom-locators} + +You can extend built-in locators API by defining an object of locator factories. These methods will exist as methods on the `page` object and any created locator. + +These locators can be useful if built-in locators are not enough. For example, when you use a custom framework for your UI. + +The locator factory needs to return a selector string or a locator itself. + +::: tip +The selector syntax is identical to Playwright locators. Please, read [their guide](https://playwright.dev/docs/other-locators) to better understand how to work with them. +::: + +```ts +import { locators } from '@vitest/browser/context' + +locators.extend({ + getByArticleTitle(title) { + return `[data-title="${title}"]` + }, + getByArticleCommentsCount(count) { + return `.comments :text("${count} comments")` + }, + async previewComments() { + // you have access to the current locator via "this" + // beware that if the method was called on `page`, `this` will be `page`, + // not the locator! + if (this !== page) { + await this.click() + } + // ... + } +}) + +// if you are using typescript, you can extend LocatorSelectors interface +// to have the autocompletion in locators.extend, page.* and locator.* methods +declare module '@vitest/browser/context' { + interface LocatorSelectors { + // if the custom method returns a string, it will be converted into a locator + // if it returns anything else, then it will be returned as usual + getByArticleTitle(title: string): Locator + getByArticleCommentsCount(count: number): Locator + + // Vitest will return a promise and won't try to convert it into a locator + previewComments(this: Locator): Promise + } +} +``` + +If the method is called on the global `page` object, then selector will be applied to the whole page. In the example bellow, `getByArticleTitle` will find all elements with an attribute `data-title` with the value of `title`. However, if the method is called on the locator, then it will be scoped to that locator. + +```html +
+ Hello, World! + +
+ +
+ Hello, Vitest! + +
+``` + +```ts +const articles = page.getByRole('article') +const worldArticle = page.getByArticleTitle('Hello, World!') // ✅ +const commentsElement = worldArticle.getByArticleCommentsCount(2) // ✅ +const wrongCommentsElement = worldArticle.getByArticleCommentsCount(0) // ❌ +const wrongElement = page.getByArticleTitle('No Article!') // ❌ + +await commentsElement.previewComments() // ✅ +await wrongCommentsElement.previewComments() // ❌ +``` diff --git a/guide/browser/multiple-setups.md b/guide/browser/multiple-setups.md index 9ec063fa..ff32df12 100644 --- a/guide/browser/multiple-setups.md +++ b/guide/browser/multiple-setups.md @@ -2,7 +2,11 @@ 自 Vitest 3 起,你可以使用新的 [`browser.instances`](/guide/browser/config#browser-instances) 选项来指定多个不同的浏览器设置。 +<<<<<<< HEAD 使用 `browser.instances` 而不是 [workspace](/guide/workspace) 的主要优势是改进了缓存。每个项目都将使用相同的 Vite 服务器,这意味着文件转换和 [依赖项预捆绑](https://vite.dev/guide/dep-pre-bundling.html) 只需进行一次。 +======= +The main advantage of using the `browser.instances` over the [test projects](/guide/projects) is improved caching. Every project will use the same Vite server meaning the file transform and [dependency pre-bundling](https://vite.dev/guide/dep-pre-bundling.html) has to happen only once. +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ## 多个浏览器 diff --git a/guide/browser/playwright.md b/guide/browser/playwright.md index d073d64b..dcc36174 100644 --- a/guide/browser/playwright.md +++ b/guide/browser/playwright.md @@ -16,9 +16,13 @@ } ``` +<<<<<<< HEAD Vitest 打开一个页面以在同一文件中运行所有测试。我们可以在 `instances` 中配置 `launch` 和 `context` 属性: +======= +Vitest opens a single page to run all tests in the same file. You can configure the `launch`, `connect` and `context` properties in `instances`: +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 -```ts{9-10} [vitest.config.ts] +```ts{9-11} [vitest.config.ts] import { defineConfig } from 'vitest/config' export default defineConfig({ @@ -28,6 +32,7 @@ export default defineConfig({ { browser: 'firefox', launch: {}, + connect: {}, context: {}, }, ], @@ -65,6 +70,14 @@ Vitest 将忽略 `launch.headless` 选项。请改用 [`test.browser.headless`]( 请注意,如果启用了 [`--inspect`](/guide/cli#inspect),Vitest 会将调试标志推送到 `launch.args`。 ::: +## connect 3.2.0 {#connect} + +These options are directly passed down to `playwright[browser].connect` command. You can read more about the command and available arguments in the [Playwright documentation](https://playwright.dev/docs/api/class-browsertype#browser-type-connect). + +::: warning +Since this command connects to an existing Playwright server, any `launch` options will be ignored. +::: + ## context Vitest 通过调用 [`browser.newContext()`](https://playwright.dev/docs/api/class-browsercontext) 为每个测试文件创建一个新的上下文。我们可以通过指定 [自定义参数](https://playwright.dev/docs/api/class-apirequest#api-request-new-context) 来配置此行为。 diff --git a/guide/cli-generated.md b/guide/cli-generated.md index c4e6eb1b..ab535b8c 100644 --- a/guide/cli-generated.md +++ b/guide/cli-generated.md @@ -89,7 +89,11 @@ - **CLI:** `--reporter ` - **Config:** [reporters](/config/#reporters) +<<<<<<< HEAD 指定 reporters +======= +Specify reporters (default, blob, verbose, dot, json, tap, tap-flat, junit, hanging-process, github-actions) +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ### outputFile @@ -98,6 +102,7 @@ 如果还指定了支持报告程序,则将测试结果写入文件,使用 cac 的点符号表示多个报告程序的单个输出结果 (比如: --outputFile.tap=./tap.txt) +<<<<<<< HEAD ### coverage.all - **CLI:** `--coverage.all` @@ -105,6 +110,8 @@ 是否在报告中包含所有文件,包括未测试的文件 +======= +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ### coverage.provider - **CLI:** `--coverage.provider ` @@ -133,6 +140,7 @@ 覆盖范围中要排除的文件。使用多个扩展名时,可指定多次(默认情况下: 访问 [`coverage.exclude`](https://vitest.dev/config/#coverage-exclude) +<<<<<<< HEAD ### coverage.extension - **CLI:** `--coverage.extension ` @@ -140,6 +148,8 @@ 包含在覆盖范围内的扩展名。使用多个扩展名时,可指定多次 (默认: `[".js", ".cjs", ".mjs", ".ts", ".mts", ".tsx", ".jsx", ".vue", ".svelte"]`) +======= +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ### coverage.clean - **CLI:** `--coverage.clean` @@ -291,7 +301,11 @@ High and low watermarks for functions in the format of `,` - **CLI:** `--workspace ` - **Config:** [workspace](/config/#workspace) +<<<<<<< HEAD 工作区配置文件的路径 +======= +[deprecated] Path to a workspace configuration file +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ### isolate @@ -360,7 +374,11 @@ High and low watermarks for functions in the format of `,` - **CLI:** `--browser.provider ` - **Config:** [browser.provider](/guide/browser/config#browser-provider) +<<<<<<< HEAD 用于运行浏览器测试的 Provider。某些浏览器只适用于特定的提供 Provider,可以是"webdriverio", "playwright", "preview",或自定义 provider. 通过 [`browser.provider`](https://vitest.dev/config/#browser-provider) 查看更多信息 (默认值: `"preview"`) +======= +Provider used to run browser tests. Some browsers are only available for specific providers. Can be "webdriverio", "playwright", "preview", or the path to a custom provider. Visit [`browser.provider`](https://vitest.dev/guide/browser/config.html#browser-provider) for more information (default: `"preview"`) +>>>>>>> 7258882dec4ec6cc31b3bfcc2df8988f7a825c02 ### browser.providerOptions @@ -761,6 +779,13 @@ Omit annotation lines from the output (default: `false`) Print basic prototype Object and Array (default: `true`) +### diff.maxDepth + +- **CLI:** `--diff.maxDepth ` +- **Config:** [diff.maxDepth](/config/#diff-maxdepth) + +Limit the depth to recurse when printing nested objects (default: `20`) + ### diff.truncateThreshold - **CLI:** `--diff.truncateThreshold ` @@ -838,6 +863,13 @@ Annotation for truncated lines (default: `... Diff result is truncated`) 自定义 tsconfig 文件的路径 +### typecheck.spawnTimeout + +- **CLI:** `--typecheck.spawnTimeout