diff --git a/api/advanced/runner.md b/api/advanced/runner.md index b7279c69..6e1df2b9 100644 --- a/api/advanced/runner.md +++ b/api/advanced/runner.md @@ -145,7 +145,11 @@ export default class Runner { ::: ::: tip +<<<<<<< HEAD 快照支持和其他功能是依赖于测试运行器的。如果你想保留这些功能,可以从 `vitest/runners` 导入 `VitestTestRunner` 并将你的测试运行器继承该类。如果你想扩展基准测试功能,它还提供了 `NodeBenchmarkRunner`。 +======= +Snapshot support and some other features depend on the runner. If you don't want to lose it, you can extend your runner from `TestRunner` imported from `vitest`. It also exposes `NodeBenchmarkRunner`, if you want to extend benchmark functionality. +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a ::: ## Tasks {#tasks} diff --git a/api/browser/locators.md b/api/browser/locators.md index 1ee3c653..1766ab09 100644 --- a/api/browser/locators.md +++ b/api/browser/locators.md @@ -1053,19 +1053,74 @@ function all(): Locator[] - [更多内容请参阅 `locator.elements()`](#elements) +### serialize + +```ts +function serialize(): SerializedLocator +``` + +Returns a JSON-serializable representation of the locator. The returned object has two fields: + +- [`selector`](#selector): the provider-specific selector string used to query the element at runtime. +- `locator`: a human-readable description of the locator (e.g. `getByRole('button')`), used for error messages and tracing. Equivalent to calling [`asLocator()`](#aslocator). + +This is primarily intended for forwarding a locator to a [browser command](/api/browser/commands), which runs in Node and cannot receive a live `Locator` instance: + +```ts +import { commands, page } from 'vitest/browser' + +await commands.myCommand(page.getByRole('button').serialize()) +``` + +::: tip +Vitest automatically serializes any `Locator` argument passed to a command, so calling `serialize()` explicitly is rarely necessary. You can also use `JSON.stringify(locator)` (it calls [`toJSON`](#tojson) internally), which produces the same result. +::: + +### toJSON + +```ts +function toJSON(): SerializedLocator +``` + +Alias of [`serialize`](#serialize). Defined so that `JSON.stringify(locator)` and structured-clone-based transports return a `SerializedLocator` object. + +### asLocator + +```ts +function asLocator(): string +``` + +Returns a human-readable description of the locator using the JavaScript locator syntax (e.g. `getByRole('button', { name: 'Submit' })`). This is the same string exposed as the `locator` field of [`serialize()`](#serialize) and is used in error messages and traces. + +```ts +import { page } from 'vitest/browser' + +const button = page.getByRole('button', { name: 'Submit' }) +button.asLocator() // "getByRole('button', { name: 'Submit' })" +``` + +::: tip +Use [`selector`](#selector) when you need the provider-specific string to forward to a [browser command](/api/browser/commands). Use `asLocator()` only for diagnostic output. The returned string is not meant to be re-used to query elements. +::: + ## Properties ### selector +<<<<<<< HEAD `selector` 是一个字符串,将由浏览器提供程序用于定位元素。Playwright 将使用 `playwright` 定位器语法,而 `preview` 和 `webdriverio` 将使用 CSS。 +======= +The `selector` is a string that will be used to locate the element by the browser provider. Playwright will use a `playwright` locator syntax, and `preview` and `webdriverio` will use CSS. +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a ::: danger 你不应在测试代码中使用此字符串。`selector` 字符串仅应在使用 Commands API 时使用: ```ts [commands.ts] import type { BrowserCommand } from 'vitest/node' +import type { SerializedLocator } from '@vitest/browser' -const test: BrowserCommand = function test(context, selector) { +const test: BrowserCommand = function test(context, { selector }) { // playwright await context.iframe.locator(selector).click() // webdriverio @@ -1078,8 +1133,13 @@ import { test } from 'vitest' import { commands, page } from 'vitest/browser' test('works correctly', async () => { +<<<<<<< HEAD await commands.test(page.getByText('Hello').selector) // ✅ // Vitest 会自动将其解包为字符串 +======= + await commands.test(page.getByText('Hello').serialize()) // ✅ + // vitest will automatically unwrap it to a SerializedLocator +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a await commands.test(page.getByText('Hello')) // ✅ }) ``` diff --git a/api/describe.md b/api/describe.md index 6ab2652a..1a1a5bbd 100644 --- a/api/describe.md +++ b/api/describe.md @@ -208,7 +208,24 @@ describe.concurrent('suite', () => { }) ``` +<<<<<<< HEAD `.skip`、`.only` 和 `.todo` 适用于并发测试套件。以下所有组合都有效: +======= +Set `concurrent` to `false` to opt out of concurrency inherited from a parent suite or [`sequence.concurrent`](/config/sequence#sequence-concurrent): + +```ts +describe.concurrent('suite', () => { + test('concurrent test', async () => { /* ... */ }) + + describe('sequential suite', { concurrent: false }, () => { + test('sequential test 1', async () => { /* ... */ }) + test('sequential test 2', async () => { /* ... */ }) + }) +}) +``` + +`.skip`, `.only`, and `.todo` works with concurrent suites. All the following combinations are valid: +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a ```ts describe.concurrent(/* ... */) @@ -230,6 +247,7 @@ describe.concurrent('suite', () => { }) ``` +<<<<<<< HEAD ## describe.sequential - **别名:** `suite.sequential` @@ -250,6 +268,8 @@ describe.concurrent('suite', () => { }) ``` +======= +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a ## describe.shuffle - **别名:** `suite.shuffle` diff --git a/api/test.md b/api/test.md index 31f9a2b3..a6e5a1c8 100644 --- a/api/test.md +++ b/api/test.md @@ -217,13 +217,21 @@ describe( 是否与测试套件中其他并发测试并行运行。 -### sequential +Set `concurrent` to `false` to opt out of concurrency inherited from [`describe.concurrent`](/api/describe#describe-concurrent) or [`sequence.concurrent`](/config/sequence#sequence-concurrent): +<<<<<<< HEAD - **类型:** `boolean` - **默认值:** `true` - **别名:** [`test.sequential`](#test-sequential) 是否按顺序运行测试。如果同时指定了 `concurrent` 和 `sequential`,`concurrent` 优先生效。 +======= +```ts +test('runs sequentially', { concurrent: false }, async () => { + // ... +}) +``` +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a ### skip @@ -453,6 +461,7 @@ test.concurrent('test 2', async ({ expect }) => { 注意,如果测试是同步的,Vitest 仍会按顺序运行它们。 +<<<<<<< HEAD ## test.sequential - **别名:** `it.sequential` @@ -478,6 +487,8 @@ describe.concurrent('suite', () => { }) ``` +======= +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a ## test.todo - **别名:** `it.todo` diff --git a/config/attachmentsdir.md b/config/attachmentsdir.md index 8887d331..31d9b8b6 100644 --- a/config/attachmentsdir.md +++ b/config/attachmentsdir.md @@ -5,7 +5,12 @@ outline: deep # attachmentsDir +<<<<<<< HEAD - **类型:** `string` - **默认值:** `'.vitest-attachments'` +======= +- **Type:** `string` +- **Default:** `'.vitest/attachments'` +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a 用于存储 [`context.annotate`](/guide/test-context#annotate) 所创建附件的目录路径(相对于项目根目录)。 diff --git a/config/browser/expect.md b/config/browser/expect.md index 94f4d4a1..3b7576c2 100644 --- a/config/browser/expect.md +++ b/config/browser/expect.md @@ -104,7 +104,15 @@ export default defineConfig({ [`attachmentsDir`](/config/attachmentsdir) 配置项提供的值,如果未配置则使用其默认值。 +<<<<<<< HEAD 例如,以下示例按浏览器分组存储截图: +======= +- `project: TestProject` 4.1.6 + + The [`TestProject`](/api/advanced/test-project) the test belongs to. + +For example, to group screenshots by browser: +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a ```ts resolveScreenshotPath: ({ arg, browserName, ext, root, testFileName }) => diff --git a/config/coverage.md b/config/coverage.md index 14ec711d..70afc50c 100644 --- a/config/coverage.md +++ b/config/coverage.md @@ -457,4 +457,19 @@ export default defineConfig({ - **可用的测试提供者:** `'v8' | 'istanbul'` - **命令行终端:** `--coverage.changed`, `--coverage.changed=` +<<<<<<< HEAD 仅收集自指定提交或分支以来更改的文件的代码覆盖率。设置为 `true` 时,使用已暂存和未暂存的更改。 +======= +Collect coverage only for files changed since a specified commit or branch. When set to `true`, it uses staged and unstaged changes. + +## coverage.autoAttachSubprocess 5.0.0 {#coverage-autoattachsubprocess} + +- **Type:** `boolean` +- **Default:** `false` +- **Available for providers:** `'v8'` +- **CLI:** `--coverage.autoAttachSubprocess` + +Track coverage of the `node:child_process` and `node:worker_threads` spawned during test run. + +Note that this option has some performance overhead as its using [`NODE_V8_COVERAGE`](https://nodejs.org/api/cli.html#node-v8-coveragedir) internally. This triggers Node to write lots of unnecessary files on file system. +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a diff --git a/config/reporters.md b/config/reporters.md index a9d74af6..8b727f04 100644 --- a/config/reporters.md +++ b/config/reporters.md @@ -14,10 +14,17 @@ interface UserConfig { type ConfigReporter = string | Reporter | [string, object?] ``` +<<<<<<< HEAD - **默认值:** [`'default'`](/guide/reporters#default-reporter)(当 `process.env.GITHUB_ACTIONS === 'true'` 时为 [['default'](/guide/reporters#default-reporter), ['github-actions'](/guide/reporters#github-actions-reporter)]) - **命令行终端:** - `--reporter=tap` 用于单个报告器 - `--reporter=verbose --reporter=github-actions` 用于多个报告器 +======= +- **Default:** [`'default'`](/guide/reporters#default-reporter). See [Default Reporters](/guide/reporters#default-reporters) for environment-specific behavior. +- **CLI:** + - `--reporter=tap` for a single reporter + - `--reporter=verbose --reporter=github-actions` for multiple reporters +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a 此选项定义在 Vitest 测试运行期间可用的单个报告器或报告器列表。 @@ -49,16 +56,24 @@ type ConfigReporter = string | Reporter | [string, object?] ::: code-group ```js [vitest.config.js] -import { defineConfig } from 'vitest/config' +import { configDefaults, defineConfig } from 'vitest/config' export default defineConfig({ test: { reporters: [ +<<<<<<< HEAD 'default', // 条件报告器 process.env.CI ? 'github-actions' : {}, // 来自 npm 包的自定义报告器 // 选项将以元组形式向下传递 +======= + ...configDefaults.reporters, + // conditional reporter + ...(process.env.CI ? ['html'] : []), + // custom reporter from npm package + // options are passed down as a tuple +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a [ 'vitest-sonar-reporter', { outputFile: 'sonar-report.xml' } diff --git a/guide/browser/visual-regression-testing.md b/guide/browser/visual-regression-testing.md index bd89ca4e..1df2c981 100644 --- a/guide/browser/visual-regression-testing.md +++ b/guide/browser/visual-regression-testing.md @@ -276,10 +276,10 @@ Reference screenshot: tests/__screenshots__/button.test.ts/button-chromium-darwin.png Actual screenshot: - tests/.vitest-attachments/button.test.ts/button-chromium-darwin-actual.png + tests/.vitest/attachments/button.test.ts/button-chromium-darwin-actual.png Diff image: - tests/.vitest-attachments/button.test.ts/button-chromium-darwin-diff.png + tests/.vitest/attachments/button.test.ts/button-chromium-darwin-diff.png ``` ### 如何解读差异图 {#understanding-the-diff-image} diff --git a/guide/cli-generated.md b/guide/cli-generated.md index 9c05409f..cad2102d 100644 --- a/guide/cli-generated.md +++ b/guide/cli-generated.md @@ -299,6 +299,13 @@ Coverage reporters to use. Visit [`coverage.reporter`](/config/coverage#coverage UI 模式和 HTML 报告器中提供的 HTML 覆盖率输出目录。 +### coverage.autoAttachSubprocess + +- **CLI:** `--coverage.autoAttachSubprocess` +- **Config:** [coverage.autoAttachSubprocess](/config/coverage#coverage-autoattachsubprocess) + +Track coverage of the `node:child_process` and `node:worker_threads` spawned during test run. Supported only by `v8` provider. (default: false) + ### mode - **命令行终端:** `--mode ` @@ -865,7 +872,11 @@ UI 模式和 HTML 报告器中提供的 HTML 覆盖率输出目录。 - **命令行终端:** `--attachmentsDir ` - **配置:** [attachmentsDir](/config/attachmentsdir) +<<<<<<< HEAD `context.annotate` 方法所生成附件的存储目录 (默认值: `.vitest-attachments`) +======= +The directory where attachments from `context.annotate` are stored in (default: `.vitest/attachments`) +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a ### run diff --git a/guide/improving-performance.md b/guide/improving-performance.md index ee44e7c2..676f893c 100644 --- a/guide/improving-performance.md +++ b/guide/improving-performance.md @@ -191,7 +191,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: blob-attachments-${{ matrix.shardIndex }} - path: .vitest-attachments/** + path: .vitest/** include-hidden-files: true retention-days: 1 @@ -222,7 +222,7 @@ jobs: - name: Download attachments from GitHub Actions Artifacts uses: actions/download-artifact@v4 with: - path: .vitest-attachments + path: .vitest pattern: blob-attachments-* merge-multiple: true diff --git a/guide/migration.md b/guide/migration.md index cba0bdd7..5a5a9ec1 100644 --- a/guide/migration.md +++ b/guide/migration.md @@ -7,7 +7,73 @@ outline: deep [迁移至 Vitest 3.0](https://v3.vitest.dev/guide/migration) | [迁移至 Vitest 2.0](https://v2.vitest.dev/guide/migration) +<<<<<<< HEAD ## 迁移至 Vitest 4.0 {#vitest-4} +======= +## Migrating to Vitest 5.0 {#vitest-5} + +::: warning Work in progress +Vitest 5.0 is currently in beta. This section tracks breaking changes as they are merged and may change before the stable release. +::: + +### Removed `test.sequential`, `describe.sequential`, and `sequential` Options + +Vitest 5.0 removes the deprecated `test.sequential`, `describe.sequential`, and `sequential` test options. Use `concurrent: false` when you need a test or suite to opt out of inherited or globally configured concurrency. + +```ts +test.sequential('example', async () => { /* ... */ }) // [!code --] +test('example', { concurrent: false }, async () => { /* ... */ }) // [!code ++] +``` + +```ts +describe.sequential('suite', () => { /* ... */ }) // [!code --] +describe('suite', { concurrent: false }, () => { /* ... */ }) // [!code ++] +``` + +The same replacement applies to option objects: + +```ts +test('example', { sequential: true }, async () => { /* ... */ }) // [!code --] +test('example', { concurrent: false }, async () => { /* ... */ }) // [!code ++] +``` + +### Locators in Commands are Serialized as Objects + +Locators forwarded to [browser commands](/api/browser/commands) are now serialized as a `SerializedLocator` object instead of a bare selector string. The object exposes two fields: + +- `selector`: the provider-specific selector string (the same value commands previously received). +- `locator`: a human-readable representation of the locator (e.g. `getByRole('button')`), used for error messages and tracing. + +Update any custom commands that accept a locator to destructure `selector` from the new object: + +```ts +import type { SerializedLocator } from '@vitest/browser' +import type { BrowserCommandContext } from 'vitest/node' + +export async function customClick( + context: BrowserCommandContext, + selector: string, // [!code --] + { selector }: SerializedLocator, // [!code ++] +) { + await context.page.locator(selector).click() +} +``` + +### Removed Deprecated Entrypoints + +Several entry points were marked as deprecated in Vitest 4.1. This release removes them entirely. + +- `vitest/coverage`: use `vitest/node` instead +- `vitest/reporters`: use `vitest/node` instead +- `vitest/environments`: use `vitest/runtime` instead +- `vitest/snapshot`: use `vitest/runtime` instead +- `vitest/runners`: use `TestRunner` from `vitest` instead +- `vitest/suite`: use static methods on `TestRunner` from vitest instead (for example, `TestRunner.getCurrentTest()`) +- `vitest/mocker` is removed completely, use `@vitest/mocker` package directly (this was published by accident at one point and never removed) +- `vitest/internal/module-runner` is removed + +## Migrating to Vitest 4.0 {#vitest-4} +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a ::: warning 前提条件 Vitest 4.0 要求 **Vite >= 6.0.0** 和 **Node.js >= 20.0.0**。 diff --git a/guide/parallelism.md b/guide/parallelism.md index fd0c745a..db7d888e 100644 --- a/guide/parallelism.md +++ b/guide/parallelism.md @@ -82,6 +82,19 @@ describe.concurrent('user API', () => { If you want *all* tests in your project to run concurrently by default, set [`sequence.concurrent`](/config/sequence#sequence-concurrent) to `true` in your config. +You can opt individual tests or suites out of inherited concurrency with `concurrent: false`: + +```ts +test('uses a shared resource', { concurrent: false }, async () => { + // ... +}) + +describe('shared resource suite', { concurrent: false }, () => { + test('step 1', async () => { /* ... */ }) + test('step 2', async () => { /* ... */ }) +}) +``` + ### Hooks with Concurrent Tests When tests run concurrently, lifecycle hooks behave differently. `beforeAll` and `afterAll` still run once for the group, but `beforeEach` and `afterEach` run for each test — potentially at the same time, since the tests themselves overlap. diff --git a/guide/reporters.md b/guide/reporters.md index a9d3a46b..233e9f5c 100644 --- a/guide/reporters.md +++ b/guide/reporters.md @@ -5,7 +5,11 @@ outline: deep # 报告器 {#reporters} +<<<<<<< HEAD Vitest 提供了几种内置报告器,以不同格式显示测试输出,以及使用自定义报告器的能力。你可以使用 `--reporter` 命令行选项,或者在你的 `outputFile` [配置选项](/config/reporters) 中加入 `reporters` 属性来选择不同的报告器。如果没有指定报告器,Vitest 将使用下文所述的默认报告器。 +======= +Vitest provides several built-in reporters to display test output in different formats, as well as the ability to use custom reporters. You can select different reporters either by using the `--reporter` command line option, or by including a `reporters` property in your [configuration file](/config/reporters). If no reporter is specified, Vitest [auto-selects reporters](#default-configuration) based on the environment. +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a 通过命令行使用报告器: @@ -35,7 +39,31 @@ export default defineConfig({ }) ``` +<<<<<<< HEAD ## 报告器输出 {#reporter-output} +======= +## Default Configuration + +When `reporters` is not configured, Vitest uses the following reporters: + +- [`default`](#default-reporter) in normal terminal runs +- [`minimal`](#minimal-reporter) when Vitest detects an AI coding agent +- [`github-actions`](#github-actions-reporter) is added when `process.env.GITHUB_ACTIONS === 'true'` + +If you configure your own reporters, the configured list replaces the default list. To add a reporter while keeping Vitest's defaults, extend `configDefaults.reporters`: + +```ts +import { configDefaults, defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + reporters: ['json', ...configDefaults.reporters], + }, +}) +``` + +## Reporter Output +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a 默认情况下,Vitest 的报告器会将输出打印到终端。当使用 `json` 、`html` 或 `junit` 报告器时,你可以在 Vite 配置文件中或通过 CLI 加入 `outputFile` [配置选项](/config/outputfile),将测试输出写入文件。 @@ -67,10 +95,17 @@ npx vitest --reporter=json --reporter=default ``` ```ts +import { configDefaults, defineConfig } from 'vitest/config' + export default defineConfig({ test: { +<<<<<<< HEAD reporters: ['json', 'default'], outputFile: './test-output.json', +======= + reporters: ['json', ...configDefaults.reporters], + outputFile: './test-output.json' +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a }, }) ``` @@ -97,11 +132,15 @@ export default defineConfig({ ### 默认报告器 {#default-reporter} +<<<<<<< HEAD 默认情况下(即如果没有指定报告器),Vitest 会在底部显示运行测试的摘要及其状态。一旦测试套件通过,其状态将被报告在摘要的顶部。 ::: tip 当 Vitest 检测到运行在 AI 智能体编程环境中时,将自动启用 [`minimal`](#minimal-reporter) 报告器以精简输出内容并优化词元 (token) 消耗。你可以通过显式配置 [`reporters`](/config/reporters) 选项来覆盖此行为。 ::: +======= +The `default` reporter displays summary of running tests and their status at the bottom. Once a suite passes, its status will be reported on top of the summary. +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a 我们可以通过配置报告器来禁用摘要: @@ -339,17 +378,78 @@ AssertionError: expected 5 to be 4 // Object.is equality ``` +<<<<<<< HEAD 输出的 XML 包含嵌套的 `testsuites` 和 `testcase` 标签。这些也可以通过报告选项 `suiteName` 和 `classnameTemplate` 进行自定义。`classnameTemplate` 可以是一个模板字符串或者一个函数。 `classnameTemplate` 选项支持的占位符有: - filename - filepath +======= +The output XML contains nested `testsuites` → `testsuite` → `testcase` tags. You can customize the reporter's behaviour with the following options: + +| Option | Description | Default | +|---|---|---| +| `suiteName` | `name` attribute of `` | `"vitest tests"` | +| `suiteNameTemplate` | Template for the `name` attribute of ``. Accepts a string with placeholders or a function. | Relative file path | +| `classnameTemplate` | Template for the `classname` attribute of ``. Accepts a string with placeholders or a function. | Relative file path | +| `titleTemplate` | Template for the `name` attribute of ``. Accepts a string with placeholders or a function. | Full test title with ancestor hierarchy | +| `ancestorSeparator` | Separator used when joining ancestor describe block names in the `{classname}` placeholder and in the default test title. | `" > "` | +| `addFileAttribute` | Add a `file` attribute to each ``. | `false` | +| `includeConsoleOutput` | Include `` / `` console output. | `true` | +| `stackTrace` | Include stack traces in `` elements. | `true` | + +The following placeholders are available for `suiteNameTemplate`: +- `{title}` – name of the first top-level `describe` block; falls back to the file basename when there is no top-level `describe` +- `{filename}` – relative file path from the root (e.g. `src/foo.test.ts`) +- `{filepath}` – absolute file path +- `{basename}` – file name without directory (e.g. `foo.test.ts`) +- `{displayName}` – Vitest project name + +The following placeholders are available for `classnameTemplate` and `titleTemplate`: +- `{classname}` – ancestor `describe` block names joined by `ancestorSeparator` (e.g. `outer > inner`) +- `{title}` – leaf test title (the string passed to `it`/`test`) +- `{suitename}` – top-level `describe` block name, empty string when the test has no enclosing `describe` +- `{filename}` – relative file path from the root +- `{filepath}` – absolute file path +- `{basename}` – file name without directory +- `{displayName}` – Vitest project name + +::: tip +`{filename}` follows Vitest's convention and resolves to the **relative path** from the project root (e.g. `src/foo.test.ts`). This differs from jest-junit where `{filename}` is the bare file name. Use `{basename}` to get only the file name. +::: +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a + +```ts +export default defineConfig({ + test: { + reporters: [ + ['junit', { + suiteName: 'My Test Suite', + // Use the first top-level describe block name as the testsuite name + suiteNameTemplate: '{title}', + // classname = ancestor describe chain + classnameTemplate: '{classname}', + // name = leaf test title only (jest-junit-compatible) + titleTemplate: '{title}', + ancestorSeparator: ' > ', + }] + ] + }, +}) +``` + +Function-based templates receive all available variables and can return any string: ```ts export default defineConfig({ test: { reporters: [ - ['junit', { suiteName: 'custom suite name', classnameTemplate: 'filename:{filename} - filepath:{filepath}' }] + ['junit', { + classnameTemplate: ({ classname, filename }) => + classname ? `${filename}::${classname}` : filename, + titleTemplate: ({ suitename, title }) => + suitename ? `[${suitename}] ${title}` : title, + }] ] }, }) @@ -565,11 +665,17 @@ export default defineConfig({ ### GitHub Actions 报告器 {#github-actions-reporter} +<<<<<<< HEAD 当测试失败时输出 [工作流命令](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message) 提供注解。当未配置 `reporters` 选项且 `process.env.GITHUB_ACTIONS === 'true'`(在GitHub Actions环境中)时,此报告器会自动启用。 +======= +Output [workflow commands](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message) +to provide annotations for test failures. This reporter is [enabled automatically](#default-configuration) when `process.env.GITHUB_ACTIONS === 'true'` (on GitHub Actions environment). +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a GitHub Actions GitHub Actions +<<<<<<< HEAD 如果已配置报告器,需显式添加 `github-actions` 添加到报告器列表中。 ```ts @@ -581,6 +687,9 @@ export default defineConfig({ ``` 你可以使用 `onWritePath` 选项自定义以 [GitHub 注解命令格式](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions) 打印的文件路径。这在容器化环境(如 Docker)中运行 Vitest 时非常有用,因为在这些环境中文件路径可能与 GitHub Actions 环境中的路径不匹配。 +======= +You can customize the file paths that are printed in [GitHub's annotation command format](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions) by using the `onWritePath` option. This is useful when running Vitest in a containerized environment, such as Docker, where the file paths may not match the paths in the GitHub Actions environment. +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a ```ts export default defineConfig({ @@ -677,7 +786,7 @@ export default defineConfig({ Outputs a minimal report containing only failed tests and their error messages. Console logs from passing tests and the summary section are also suppressed. ::: tip Agent Reporter -This reporter is well optimized for AI coding assistants and LLM-based workflows to reduce token usage. It is automatically enabled when no `reporters` option is configured and Vitest detects it is running inside an AI coding agent. If you configure custom reporters, you can explicitly add `minimal` or `agent`: +This reporter is well optimized for AI coding assistants and LLM-based workflows to reduce token usage. It is [enabled automatically](#default-configuration) when Vitest detects it is running inside an AI coding agent. :::code-group ```bash [CLI] diff --git a/guide/snapshot.md b/guide/snapshot.md index 3d03eda5..b990e4a9 100644 --- a/guide/snapshot.md +++ b/guide/snapshot.md @@ -337,7 +337,7 @@ Custom serializers control how values are _rendered_ into snapshot strings, but A domain adapter implements four methods and is generic over two types — `Captured` (what the value actually is) and `Expected` (what the stored snapshot parses into): ```ts -import type { DomainMatchResult, DomainSnapshotAdapter } from '@vitest/snapshot' +import type { DomainMatchResult, DomainSnapshotAdapter } from 'vitest' const myAdapter: DomainSnapshotAdapter = { name: 'my-domain', @@ -413,7 +413,7 @@ expect(value).toMatchMyDomainInlineSnapshot(`key=value`) A minimal adapter that stores objects as `key=value` lines, with regex pattern and subset key match support ([full source](https://github.com/vitest-dev/vitest/blob/main/test/snapshots/test/fixtures/domain/basic.ts)): ```ts [kv-adapter.ts] -import type { DomainMatchResult, DomainSnapshotAdapter } from '@vitest/snapshot' +import type { DomainMatchResult, DomainSnapshotAdapter } from 'vitest' type KVCaptured = Record type KVExpected = Record diff --git a/guide/ui.md b/guide/ui.md index 3a3a9542..863a5853 100644 --- a/guide/ui.md +++ b/guide/ui.md @@ -40,7 +40,11 @@ export default defineConfig({ 你可以在 Vitest UI 中查看覆盖率报告:查看 [覆盖率 | UI 模式](/guide/coverage#vitest-ui) 了解更多详情。 ::: warning +<<<<<<< HEAD 如果你仍想在终端中实时查看测试的运行情况,请不要忘记将 `default` 报告器添加到 `reporters` 选项:`['default', 'html']`。 +======= +If you still want to see how your tests are running in real time in the terminal, add `configDefaults.reporters` to the `reporters` option: `['html', ...configDefaults.reporters]`. +>>>>>>> ad185a835a130e727cdfb4ac909f05238364dc6a ::: ::: tip