diff --git a/.vitepress/components/FeaturesList.vue b/.vitepress/components/FeaturesList.vue
index 56cbafd2..4d8ff746 100644
--- a/.vitepress/components/FeaturesList.vue
+++ b/.vitepress/components/FeaturesList.vue
@@ -1,10 +1,29 @@
+<<<<<<< HEAD
+=======
+
+ Vite's config, transformers, resolvers, and plugins
+ Use the same setup from your app to run the tests!
+ Smart & instant watch mode, like HMR for tests!
+ Component testing for Vue, React, Svelte, Lit, Marko and more
+ Out-of-the-box TypeScript / JSX support
+ ESM first, top level await
+ Workers multi-threading via Tinypool
+ Benchmarking support with Tinybench
+ Filtering, timeouts, concurrent for suite and tests
+ Projects support
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
与
Vite
通用的配置、转换器、解析器和插件。
+<<<<<<< HEAD
使用与你的应用相同的设置来运行测试!
智能文件监听模式,就像是测试的 HMR!
支持对 Vue、React、Svelte、Lit等框架进行组件测试。
@@ -82,6 +101,17 @@
进行类型测试
支持分片
+=======
+ Chai built-in for assertions + Jest expect compatible APIs
+ Tinyspy built-in for mocking
+ happy-dom or jsdom for DOM mocking
+ Browser Mode for running component tests in the browser
+ Code coverage via v8 or istanbul
+ Rust-like in-source testing
+ Type Testing via expect-type
+ Sharding Support
+ Reporting Uncaught Errors
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
diff --git a/.vitepress/config.ts b/.vitepress/config.ts
index 9d01d1b4..393b1d67 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',
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
},
{
text: '报告器「Reporters」',
@@ -489,7 +494,15 @@ function guide(): DefaultTheme.SidebarItem[] {
link: '/guide/mocking',
},
{
+<<<<<<< HEAD
text: '类型测试',
+=======
+ text: 'Parallelism',
+ link: '/guide/parallelism',
+ },
+ {
+ text: 'Testing Types',
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
link: '/guide/testing-types',
},
{
diff --git a/advanced/api/index.md b/advanced/api/index.md
index 710e7a36..481c324a 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
另外请注意,`viteConfig.test` 不会被完全解析。如果你需要 Vitest 配置,请使用 `vitestConfig` 代替。
:::
diff --git a/advanced/api/plugin.md b/advanced/api/plugin.md
index fad03683..63e3ac9e 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
## 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:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
项目的 `configFile` 可以在 Vite 的配置中访问:`project.vite.config.configFile`。
diff --git a/advanced/api/test-project.md b/advanced/api/test-project.md
index fece1516..596515ea 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
:::
## 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',
+ },
+ },
+ ],
+ },
+})
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```
:::
::: 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
:::
## 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
:::
## onTestsRerun
diff --git a/advanced/api/vitest.md b/advanced/api/vitest.md
index 4966efbe..ec3781e9 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`.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
::: 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
## 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
根项目的主要目标是设置全局配置。实际上,`rootProject.config` 直接引用 `rootProject.globalConfig` 和 `vitest.config`:
@@ -433,7 +447,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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
:::
## close
diff --git a/advanced/pool.md b/advanced/pool.md
index a2180da1..864f35b0 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:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```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` 文件。
:::
+=======
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
## 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
Vitest 会等到 `runTests` 执行完毕后才结束运行(即只有在 `runTests` 解决后才会触发 [`onFinished`](/advanced/reporters))。
diff --git a/advanced/runner.md b/advanced/runner.md
index 84fb57eb..8021a010 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
*/
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()`.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
*/
pending?: boolean
/**
diff --git a/api/expect.md b/api/expect.md
index dd671bb4..5992c068 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`
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
这样可以确保一个值与最近的快照匹配。
@@ -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`
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
这确保了一个值与最近的快照相匹配。
@@ -848,7 +856,11 @@ test('matches snapshot', () => {
## toMatchFileSnapshot {#tomatchfilesnapshot}
+<<<<<<< HEAD
- **类型:** `(filepath: string, message?: string) => Promise`
+=======
+- **Type:** `(filepath: string, hint?: string) => Promise`
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
指定文件内容与快照进行比较或更新(而非使用 `.snap` 文件)。
@@ -865,13 +877,21 @@ it('render basic', async () => {
## toThrowErrorMatchingSnapshot
+<<<<<<< HEAD
- **类型:** `(message?: string) => void`
+=======
+- **Type:** `(hint?: string) => void`
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
与 [`toMatchSnapshot`](#tomatchsnapshot) 相同,但期望的值与 [`toThrowError`](#tothrowerror) 相同。
## toThrowErrorMatchingInlineSnapshot
+<<<<<<< HEAD
- **类型:** `(snapshot?: string, message?: string) => void`
+=======
+- **Type:** `(snapshot?: string, hint?: string) => void`
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
与 [`toMatchInlineSnapshot`](#tomatchinlinesnapshot) 类似,但期望的值与 [`toThrowError`](#tothrowerror) 相同。
diff --git a/api/index.md b/api/index.md
index c413096a..487fdb48 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:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```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
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
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)
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
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:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```ts
import { bench } from 'vitest'
@@ -1359,6 +1387,7 @@ test('performs an organization query', async () => {
```
::: tip
+<<<<<<< HEAD
此 hook 始终以相反的顺序调用,并且不受 [`sequence.hooks`](/config/#sequence-hooks) 选项的影响。
@@ -1372,6 +1401,9 @@ test('skipped dynamically', (t) => {
})
```
+=======
+This hook is always called in reverse order and is not affected by [`sequence.hooks`](/config/#sequence-hooks) option.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
:::
### onTestFailed
diff --git a/api/vi.md b/api/vi.md
index 3196a523..bb95aac0 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:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```ts
const cart = {
diff --git a/blog/vitest-3.md b/blog/vitest-3.md
index c410b555..2744d873 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:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```jsx
import { defineConfig } from 'vitest/config'
diff --git a/config/index.md b/config/index.md
index 7e5242e1..a9d966d6 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
:::
### include
@@ -139,9 +143,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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
### server {#server}
@@ -466,7 +476,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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```ts [vitest.config.js]
import AutoImport from 'unplugin-auto-import/vite'
@@ -583,7 +608,11 @@ jsdom 环境变量导出了等同于当前[JSDOM](https://github.com/jsdom/jsdom
- **默认值:** `[]`
::: danger DEPRECATED
+<<<<<<< HEAD
此 API 在 Vitest 3 中已弃用。请使用 [workspace](/guide/workspace) 来定义不同的配置。
+=======
+This API was deprecated in Vitest 3. Use [projects](/guide/projects) to define different configurations instead.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```ts
export default defineConfig({
@@ -591,7 +620,7 @@ export default defineConfig({
environmentMatchGlobs: [ // [!code --]
['./*.jsdom.test.ts', 'jsdom'], // [!code --]
], // [!code --]
- workspace: [ // [!code ++]
+ projects: [ // [!code ++]
{ // [!code ++]
extends: true, // [!code ++]
test: { // [!code ++]
@@ -630,7 +659,11 @@ export default defineConfig({
- **默认值:** `[]`
::: danger DEPRECATED
+<<<<<<< HEAD
此 API 在 Vitest 3 中已被弃用。请使用 [workspace](/guide/workspace) 来定义不同的配置:
+=======
+This API was deprecated in Vitest 3. Use [projects](/guide/projects) to define different configurations instead:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```ts
export default defineConfig({
@@ -638,7 +671,7 @@ export default defineConfig({
poolMatchGlobs: [ // [!code --]
['./*.threads.test.ts', 'threads'], // [!code --]
], // [!code --]
- workspace: [ // [!code ++]
+ projects: [ // [!code ++]
{ // [!code ++]
test: { // [!code ++]
extends: true, // [!code ++]
@@ -692,6 +725,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)$/,
+ testToRun: (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`
@@ -1651,7 +1714,11 @@ Sets thresholds to 100 for files matching the glob pattern.
- **可用的测试提供者:** `'v8'`
- **命令行终端:** `--coverage.ignoreEmptyLines=`
+<<<<<<< HEAD
忽略空行、注释和其他非运行时代码,如 Typescript 类型。
+=======
+Ignore empty lines, comments and other non-runtime code, e.g. Typescript types. Requires `experimentalAstAwareRemapping: false`.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
该选项只有在使用的编译器删除了转译代码中的注释和其他非运行时代码时才有效。
默认情况下,Vite 使用 ESBuild,它会删除 `.ts`、`.tsx` 和 `.jsx` 文件中的注释和 Typescript 类型。
@@ -1675,6 +1742,14 @@ export default defineConfig({
},
})
```
+#### coverage.experimentalAstAwareRemapping
+
+- **Type:** `boolean`
+- **Default:** `false`
+- **Available for providers:** `'v8'`
+- **CLI:** `--coverage.experimentalAstAwareRemapping=`
+
+Remap coverage with experimental AST based analysis. Provides more accurate results compared to default mode.
#### coverage.ignoreClassMethods
@@ -2007,7 +2082,11 @@ export default defineConfig({
### sequence
+<<<<<<< HEAD
- **类型**: `{ sequencer?, shuffle?, seed?, hooks?, setupFiles? }`
+=======
+- **Type**: `{ sequencer?, shuffle?, seed?, hooks?, setupFiles?, groupOrder }`
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
配置测试运行顺序的选项。
@@ -2026,6 +2105,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 +2314,13 @@ Vitest 通常使用缓存对测试进行排序,因此长时间运行的测试
自定义 tsconfig 的路径,相对于项目根目录。
+#### typecheck.spawnTimeout
+
+- **Type**: `number`
+- **Default**: `10_000`
+
+Minimum time in milliseconds it takes to spawn the typechecker.
+
### slowTestThreshold
- **类型**: `number`
@@ -2424,14 +2575,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).
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
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`
diff --git a/guide/browser/commands.md b/guide/browser/commands.md
index 912055d7..aa5ed655 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
默认情况下,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..d0ee1d09 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/).
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
:::
@@ -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:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```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:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
-{#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',
+ },
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
},
- },
+ {
+ 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).
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
## Headless
@@ -536,7 +590,7 @@ test('shows the children when the checkbox is checked', async () => {
})
```
```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 +617,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'
diff --git a/guide/browser/locators.md b/guide/browser/locators.md
index e97a9c0d..690eca4f 100644
--- a/guide/browser/locators.md
+++ b/guide/browser/locators.md
@@ -769,6 +769,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 +798,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 +955,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..b025f363 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.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
## 多个浏览器
diff --git a/guide/browser/playwright.md b/guide/browser/playwright.md
index d073d64b..167b2e06 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`:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
-```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..eda90d4d 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, basic, blob, verbose, dot, json, tap, tap-flat, junit, hanging-process, github-actions)
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
### outputFile
@@ -291,7 +295,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
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
### isolate
@@ -360,7 +368,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"`)
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
### browser.providerOptions
@@ -761,6 +773,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 `
diff --git a/guide/coverage.md b/guide/coverage.md
index 094b0cb1..bc45be67 100644
--- a/guide/coverage.md
+++ b/guide/coverage.md
@@ -193,25 +193,35 @@ export default defineConfig({
- [`v8`](https://github.com/istanbuljs/v8-to-istanbul#ignoring-uncovered-lines)
- [`ìstanbul`](https://github.com/istanbuljs/nyc#parsing-hints-ignoring-lines)
+- `v8` with [`experimentalAstAwareRemapping: true`](https://vitest.dev/config/#coverage-experimentalAstAwareRemapping) see [ast-v8-to-istanbul | Ignoring code](https://github.com/AriPerkkio/ast-v8-to-istanbul?tab=readme-ov-file#ignoring-code)
使用 TypeScript 时,源代码使用 `esbuild` 进行转译,这会从源代码中删除所有注释([esbuild#516](https://github.com/evanw/esbuild/issues/516))。
被视为[合法注释](https://esbuild.github.io/api/#legal-comments)的注释将被保留。
+<<<<<<< HEAD
对于 `istanbul` 测试提供者,你可以在忽略提示中包含 `@preserve` 关键字。
请注意,这些忽略提示现在也可能包含在最终的产品构建中。
+=======
+You can include a `@preserve` keyword in the ignore hint.
+Beware that these ignore hints may now be included in final production build as well.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```diff
-/* istanbul ignore if */
+/* istanbul ignore if -- @preserve */
if (condition) {
-```
+<<<<<<< HEAD
不幸的是,目前这在 `v8` 中不起作用。你通常可以在 TypeScript 使用 `v8 ignore` 注释:
```ts
/* v8 ignore next 3 */
+=======
+-/* v8 ignore if */
++/* v8 ignore if -- @preserve */
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
if (condition) {
```
diff --git a/guide/environment.md b/guide/environment.md
index 3bc4a14e..2db1aa88 100644
--- a/guide/environment.md
+++ b/guide/environment.md
@@ -22,7 +22,11 @@ Vitest 提供 [`environment`](/config/#environment) 选项以在特定环境中
::: warning
"环境" 仅在 Node.js 中运行测试时存在。
+<<<<<<< HEAD
在 Vitest 中,`浏览器` 不被视为一个环境。如果希望使用[浏览器模式](/guide/browser/)运行部分测试,可以创建一个[workspace project](/guide/browser/#workspace-config)。
+=======
+`browser` is not considered an environment in Vitest. If you wish to run part of your tests using [Browser Mode](/guide/browser/), you can create a [test project](/guide/browser/#projects-config).
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
:::
## 特定文件的环境
diff --git a/guide/extending-matchers.md b/guide/extending-matchers.md
index c3993aa8..c025dfac 100644
--- a/guide/extending-matchers.md
+++ b/guide/extending-matchers.md
@@ -25,7 +25,19 @@ expect.extend({
如果你使用 TypeScript,你可以使用以下代码在环境声明文件(例如:`vitest.d.ts`)中扩展默认的 `Assertion` 接口:
-```ts
+::: code-group
+```ts [3.2.0]
+import 'vitest'
+
+interface CustomMatchers {
+ toBeFoo: () => R
+}
+
+declare module 'vitest' {
+ interface Matchers extends CustomMatchers {}
+}
+```
+```ts [3.0.0]
import 'vitest'
interface CustomMatchers {
@@ -37,6 +49,11 @@ declare module 'vitest' {
interface AsymmetricMatchersContaining extends CustomMatchers {}
}
```
+:::
+
+::: tip
+Since Vitest 3.2, you can extend the `Matchers` interface to have type-safe assertions in `expect.extend`, `expect().*`, and `expect.*` methods at the same time. Previously, you had to define separate interfaces for each of them.
+:::
::: warning
不要忘记在 `tsconfig.json` 中包含声明文件。
@@ -56,35 +73,77 @@ interface ExpectationResult {
```
::: warning
+<<<<<<< HEAD
如果你创建了一个异步断言,记得在测试代码的结果前使用 `await` 关键字(`await expect('foo').toBeFoo()`)
+=======
+If you create an asynchronous matcher, don't forget to `await` the result (`await expect('foo').toBeFoo()`) in the test itself::
+
+```ts
+expect.extend({
+ async toBeAsyncAssertion() {
+ // ...
+ }
+})
+
+await expect().toBeAsyncAssertion()
+```
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
:::
断言的第一个参数是接收值(即 `expect(received)` 中的 received ),其余参数将直接传给断言。
+<<<<<<< HEAD
断言方法可以访问上下文 `this` 对象中的这些属性:
+=======
+Matcher function has access to `this` context with the following properties:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
-- `isNot`
+### `isNot`
+<<<<<<< HEAD
如果断言是在 `not` 方法上调用的( `expect(received).not.toBeFoo()` ),则返回 true。
+=======
+Returns true, if matcher was called on `not` (`expect(received).not.toBeFoo()`).
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
-- `promise`
+### `promise`
+<<<<<<< HEAD
如果断言是在 `resolved/rejected` 中调用的,它的值将包含此断言的名称。否则,它将是一个空字符串。
+=======
+If matcher was called on `resolved/rejected`, this value will contain the name of modifier. Otherwise, it will be an empty string.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
-- `equals`
+### `equals`
+<<<<<<< HEAD
这是一个工具函数,他可以帮助你比较两个值。如果是相同的则返回 true,反之返回 false。这个方法几乎在每个断言内部都有使用。默认情况下,它支持非对称的断言。
+=======
+This is a utility function that allows you to compare two values. It will return `true` if values are equal, `false` otherwise. This function is used internally for almost every matcher. It supports objects with asymmetric matchers by default.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
-- `utils`
+### `utils`
+<<<<<<< HEAD
它包含了一系列工具函数,你可以使用它们来显示信息。
+=======
+This contains a set of utility functions that you can use to display messages.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
`this` 上下文也包含了当前测试的信息,你可以通过调用 `expect.getState()` 来获取它,其中最有用的属性是:
-- `currentTestName`
+### `currentTestName`
+<<<<<<< HEAD
当前测试的全称(包括 describe 块)。
+=======
+Full name of the current test (including describe block).
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
-- `testPath`
+### `testPath`
+<<<<<<< HEAD
当前测试的路径。
+=======
+Path to the current test.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
diff --git a/guide/features.md b/guide/features.md
index 931ac83a..cf40e87a 100644
--- a/guide/features.md
+++ b/guide/features.md
@@ -34,7 +34,11 @@ $ vitest
## 多线程
+<<<<<<< HEAD
默认情况下,Vitest 通过 [Tinypool](https://github.com/tinylibs/tinypool)([Piscina](https://github.com/piscinajs/piscina) 的轻量级分叉)使用 [`node:child_process`](https://nodejs.org/api/child_process.html),在多个进程中运行测试文件,允许测试同时运行。如果想进一步加快测试套件的速度,可以考虑启用 `--pool=threads`,使用 [`node:worker_threads`](https://nodejs.org/api/worker_threads.html)来运行测试(注意,某些软件包可能无法使用此设置)。
+=======
+By default Vitest runs test files in [multiple processes](/guide/parallelism) using [`node:child_process`](https://nodejs.org/api/child_process.html) via [Tinypool](https://github.com/tinylibs/tinypool) (a lightweight fork of [Piscina](https://github.com/piscinajs/piscina)), allowing tests to run simultaneously. If you want to speed up your test suite even further, consider enabling `--pool=threads` to run tests using [`node:worker_threads`](https://nodejs.org/api/worker_threads.html) (beware that some packages might not work with this setup).
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
要在单个线程或进程中运行测试,查看 [`poolOptions`](/config/#pooloptions) 了解更多消息。
@@ -279,3 +283,60 @@ export default defineConfig(({ mode }) => ({
},
}))
```
+
+## Unhandled Errors
+
+By default, Vitest catches and reports all [unhandled rejections](https://developer.mozilla.org/en-US/docs/Web/API/Window/unhandledrejection_event), [uncaught exceptions](https://nodejs.org/api/process.html#event-uncaughtexception) (in Node.js) and [error](https://developer.mozilla.org/en-US/docs/Web/API/Window/error_event) events (in the [browser](/guide/browser/)).
+
+You can disable this behaviour by catching them manually. Vitest assumes the callback is handled by you and won't report the error.
+
+::: code-group
+```ts [setup.node.js]
+// in Node.js
+process.on('unhandledRejection', () => {
+ // your own handler
+})
+
+process.on('uncaughtException', () => {
+ // your own handler
+})
+```
+```ts [setup.browser.js]
+// in the browser
+window.addEventListener('error', () => {
+ // your own handler
+})
+
+window.addEventListener('unhandledrejection', () => {
+ // your own handler
+})
+```
+:::
+
+Alternatively, you can also ignore reported errors with a [`dangerouslyIgnoreUnhandledErrors`](/config/#dangerouslyignoreunhandlederrors) option. Vitest will still report them, but they won't affect the test result (exit code won't be changed).
+
+If you need to test that error was not caught, you can create a test that looks like this:
+
+```ts
+test('my function throws uncaught error', async ({ onTestFinished }) => {
+ onTestFinished(() => {
+ // if the event was never called during the test,
+ // make sure it's removed before the next test starts
+ process.removeAllListeners('unhandledrejection')
+ })
+
+ return new Promise((resolve, reject) => {
+ process.once('unhandledrejection', (error) => {
+ try {
+ expect(error.message).toBe('my error')
+ resolve()
+ }
+ catch (error) {
+ reject(error)
+ }
+ })
+
+ callMyFunctionThatRejectsError()
+ })
+})
+```
diff --git a/guide/in-source.md b/guide/in-source.md
index 42e5d538..1f4dd591 100644
--- a/guide/in-source.md
+++ b/guide/in-source.md
@@ -54,8 +54,10 @@ $ npx vitest
对于生产环境的构建,你需要设置配置文件内的 `define` 选项,让打包器清除无用的代码。例如,在 Vite 中
-```ts [vitest.config.ts]
-import { defineConfig } from 'vitest/config'
+```ts [vite.config.ts]
+///
+
+import { defineConfig } from 'vite'
export default defineConfig({
test: {
diff --git a/guide/index.md b/guide/index.md
index 448a947d..c3cc945d 100644
--- a/guide/index.md
+++ b/guide/index.md
@@ -179,17 +179,23 @@ export default defineConfig({
但我们建议 Vite 和 Vitest 使用相同的文件,而不是创建两个单独的文件。
:::
+<<<<<<< HEAD
## 支持工作空间
在同一个项目中使用 [Vitest 工作区](/guide/workspace)运行不同的项目配置。你可以在 `vitest.config` 文件中定义一个包含文件和文件夹的列表来指定你的工作区。
+=======
+## Projects Support
+
+Run different project configurations inside the same project with [Test Projects](/guide/projects). You can define a list of files and folders that define your projects in `vitest.config` file.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
- workspace: [
- // you can use a list of glob patterns to define your workspaces
+ projects: [
+ // you can use a list of glob patterns to define your projects
// Vitest expects a list of config files
// or directories where there is a config file
'packages/*',
@@ -265,7 +271,7 @@ export default defineConfig({
| `sveltekit` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/sveltekit) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/sveltekit?initialPath=__vitest__/) |
| `profiling` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/profiling) | Not Available |
| `typecheck` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/typecheck) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/typecheck?initialPath=__vitest__/) |
-| `workspace` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/workspace) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/workspace?initialPath=__vitest__/) |
+| `projects` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/projects) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/projects?initialPath=__vitest__/) |
## 使用 Vitest 的项目
diff --git a/guide/parallelism.md b/guide/parallelism.md
new file mode 100644
index 00000000..d856c932
--- /dev/null
+++ b/guide/parallelism.md
@@ -0,0 +1,37 @@
+---
+title: Parallelism | Guide
+outline: deep
+---
+
+# Parallelism
+
+## File Parallelism
+
+By default, Vitest runs _test files_ in parallel. Depending on the specified `pool`, Vitest uses a different mechanism to parallelize test files:
+
+- `forks` (the default) and `vmForks` run tests in different [child processes](https://nodejs.org/api/child_process.html)
+- `threads` and `vmThreads` run tests in different [worker threads](https://nodejs.org/api/worker_threads.html)
+
+Both "child processes" and "worker threads" are refered to as "workers". You can configure the number of running workers with [`minWorkers`](/config/#minworkers) and [`maxWorkers`](/config/#maxworkers) options. Or more granually with [`poolOptions`](/config/#pooloptions) configuration.
+
+If you have a lot of tests, it is usually faster to run them in parallel, but it also depends on the project, the environment and [isolation](/config/#isolate) state. To disable file parallelisation, you can set [`fileParallelism`](/config/#fileparallelism) to `false`. To learn more about possible performance improvements, read the [Performance Guide](/guide/improving-performance).
+
+## Test Parallelism
+
+Unlike _test files_, Vitest runs _tests_ in sequence. This means that tests inside a single test file will run in the order they are defined.
+
+Vitest supports the [`concurrent`](/api/#test-concurrent) option to run tests together. If this option is set, Vitest will group concurrent tests in the same _file_ (the number of simultaneously running tests depends on the [`maxConcurrency`](/config/#maxconcurrency) option) and run them with [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all).
+
+Vitest doesn't perform any smart analysis and doesn't create additional workers to run these tests. This means that the performance of your tests will improve only if you rely heavily on asynchronous operations. For example, these tests will still run one after another even though the `concurrent` option is specified. This is because they are synchronous:
+
+```ts
+test.concurrent('the first test', () => {
+ expect(1).toBe(1)
+})
+
+test.concurrent('the second test', () => {
+ expect(2).toBe(2)
+})
+```
+
+If you wish to run all tests concurrently, you can set the [`sequence.concurrent`](/config/#sequence-concurrent) option to `true`.
diff --git a/guide/workspace.md b/guide/projects.md
similarity index 63%
rename from guide/workspace.md
rename to guide/projects.md
index 7f6df597..68de392f 100644
--- a/guide/workspace.md
+++ b/guide/projects.md
@@ -1,31 +1,51 @@
---
+<<<<<<< HEAD:guide/workspace.md
title: 工作空间 | 指南
---
# 工作空间
+=======
+title: Test Projects | Guide
+---
+
+# Test Projects
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458:guide/projects.md
::: tip Sample Project
-[GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/workspace) - [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/workspace?initialPath=__vitest__/)
+[GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/projects) - [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/projects?initialPath=__vitest__/)
:::
+<<<<<<< HEAD:guide/workspace.md
Vitest 提供了在单个 Vitest 进程中定义多个项目配置的方法。该功能对单核设置尤为有用,但也可用于运行不同配置的测试,如 `resolve.alias`、`plugins` 或 `test.browser` 等。
## 定义工作空间
从 Vitest 3 开始,你可以在根 [配置](/config/) 中定义工作区。在这种情况下,如果根目录下存在 `vitest.workspace` 文件,Vitest 将会忽略它。
+=======
+::: warning
+This feature is also known as a `workspace`. The `workspace` is deprecated since 3.2 and replaced with the `projects` configuration. They are functionally the same.
+:::
+
+Vitest provides a way to define multiple project configurations within a single Vitest process. This feature is particularly useful for monorepo setups but can also be used to run tests with different configurations, such as `resolve.alias`, `plugins`, or `test.browser` and more.
+
+## Defining Projects
+
+You can define projects in your root [config](/config/):
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458:guide/projects.md
```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
- workspace: ['packages/*'],
+ projects: ['packages/*'],
},
})
```
+<<<<<<< HEAD:guide/workspace.md
如果你使用的是较早的版本,工作区必须在其根目录中包含 `vitest.workspace` 或 `vitest.projects` 文件(如果不存在,则位于根配置文件所在的文件夹或工作目录中)。请注意,`projects` 只是一个别名,并不会改变此功能的行为或语义。Vitest 支持该文件的 `ts`、`js` 和 `json` 扩展名。
::: tip NAMING
@@ -35,57 +55,59 @@ export default defineConfig({
:::code-group
```ts [vitest.config.ts 3.0.0]
+=======
+Project configurations are inlined configs, files, or glob patterns referencing your projects. For example, if you have a folder named `packages` that contains your projects, you can define an array in your root Vitest config:
+
+```ts [vitest.config.ts]
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458:guide/projects.md
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
- workspace: ['packages/*'],
+ projects: ['packages/*'],
},
})
```
-```ts [vitest.workspace.ts]
-export default [
- 'packages/*'
-]
-```
-:::
+<<<<<<< HEAD:guide/workspace.md
Vitest 会将 `packages` 中的每个文件夹视为一个独立的项目,即使它里面没有配置文件。如果这个全局模式匹配到任何文件,即使文件名中没有 `vitest`,也会被视作 Vitest 的配置文件。
::: warning
Vitest 不会将根目录下的 `vitest.config` 文件视为工作区项目,除非在工作区配置中明确指定。因此,根配置只会影响全局选项,例如 `reporters` 和 `coverage`。请注意,Vitest 将始终运行根配置文件中指定的某些插件钩子,例如 `apply`、`config`、`configResolved` 或 `configureServer`。Vitest 还使用相同的插件来执行全局设置、工作区文件和自定义覆盖率提供者。
+=======
+Vitest will treat every folder in `packages` as a separate project even if it doesn't have a config file inside. If this glob pattern matches _any file_, it will be considered a Vitest config even if it doesn't have a `vitest` in its name or has an obscure file extension.
+
+::: warning
+Vitest does not treat the root `vitest.config` file as a project unless it is explicitly specified in the configuration. Consequently, the root configuration will only influence global options such as `reporters` and `coverage`. Note that Vitest will always run certain plugin hooks, like `apply`, `config`, `configResolved` or `configureServer`, specified in the root config file. Vitest also uses the same plugins to execute global setups and custom coverage provider.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458:guide/projects.md
:::
你还可以使用项目的配置文件引用项目:
-:::code-group
-```ts [vitest.config.ts 3.0.0]
+```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
- workspace: ['packages/*/vitest.config.{e2e,unit}.ts'],
+ projects: ['packages/*/vitest.config.{e2e,unit}.ts'],
},
})
```
-```ts [vitest.workspace.ts]
-export default [
- 'packages/*/vitest.config.{e2e,unit}.ts'
-]
-```
-:::
该模式仅包括具有包含 `e2e` 或 `unit` 的 `vitest.config` 文件的项目。这些关键字需要在文件扩展名之前出现。
+<<<<<<< HEAD:guide/workspace.md
你也可以使用内联配置来定义项目。工作区配置同时支持这两种语法。
+=======
+You can also define projects using inline configuration. The configuration supports both syntaxes simultaneously.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458:guide/projects.md
-:::code-group
-```ts [vitest.config.ts 3.0.0]
+```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
- workspace: [
+ projects: [
// matches every folder and file inside the `packages` folder
'packages/*',
{
@@ -101,7 +123,8 @@ export default defineConfig({
{
test: {
include: ['tests/**/*.{node}.test.{ts,js}'],
- name: 'node',
+ // color of the name label can be changed
+ name: { label: 'node', color: 'green' },
environment: 'node',
}
}
@@ -109,38 +132,12 @@ export default defineConfig({
}
})
```
-```ts [vitest.workspace.ts]
-import { defineWorkspace } from 'vitest/config'
-
-// defineWorkspace provides a nice type hinting DX
-export default defineWorkspace([
- // matches every folder and file inside the `packages` folder
- 'packages/*',
- {
- // add "extends" to merge two configs together
- extends: './vite.config.js',
- test: {
- include: ['tests/**/*.{browser}.test.{ts,js}'],
- // it is recommended to define a name when using inline configs
- name: 'happy-dom',
- environment: 'happy-dom',
- }
- },
- {
- test: {
- include: ['tests/**/*.{node}.test.{ts,js}'],
- name: 'node',
- environment: 'node',
- }
- }
-])
-```
-:::
::: warning
所有项目都必须有唯一的名称,否则 Vitest 会出错。如果内联配置中没有提供名称,Vitest 将分配一个数字。对于使用 glob 语法定义的项目配置,Vitest 将默认使用最近的 `package.json` 文件中的 "name" 属性,如果不存在,则使用文件夹名称。
:::
+<<<<<<< HEAD:guide/workspace.md
如果我们不使用内联配置,我们可以在根目录创建一个小的 JSON 文件,或者仅仅在根配置中指定它:
```json [vitest.workspace.json]
@@ -148,6 +145,9 @@ export default defineWorkspace([
```
工作区项目不支持所有配置属性。为了提高类型安全性,请在项目配置文件中使用 `defineProject` 方法而不是 `defineConfig` 方法:
+=======
+Projects do not support all configuration properties. For better type safety, use the `defineProject` method instead of `defineConfig` within project configuration files:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458:guide/projects.md
```ts twoslash [packages/a/vitest.config.ts]
// @errors: 2769
@@ -165,7 +165,11 @@ export default defineProject({
## 运行测试
+<<<<<<< HEAD:guide/workspace.md
要在工作区内运行测试,请在根目录 `package.json` 中定义一个脚本:
+=======
+To run tests, define a script in your root `package.json`:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458:guide/projects.md
```json [package.json]
{
@@ -234,7 +238,11 @@ bun run test --project e2e --project unit
## 配置
+<<<<<<< HEAD:guide/workspace.md
即使工作区是在根级配置文件中定义的,而不是在单独的 `vitest.workspace` 文件中定义的,也不会从根级配置文件中继承任何配置选项。我们可以创建一个共享配置文件,并手动将其与项目配置合并:
+=======
+None of the configuration options are inherited from the root-level config file. You can create a shared config file and merge it with the project config yourself:
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458:guide/projects.md
```ts [packages/a/vitest.config.ts]
import { defineProject, mergeConfig } from 'vitest/config'
@@ -250,10 +258,17 @@ export default mergeConfig(
)
```
+<<<<<<< HEAD:guide/workspace.md
此外,在 `defineWorkspace` 层级,我们可以使用 `extends` 选项来继承根级别的配置。所有选项将被合并。
::: code-group
```ts [vitest.config.ts 3.0.0]
+=======
+Additionally, you can use the `extends` option to inherit from your root-level configuration. All options will be merged.
+
+```ts [vitest.config.ts]
+import { defineConfig } from 'vitest/config'
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458:guide/projects.md
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vitest/config'
@@ -261,7 +276,7 @@ export default defineConfig({
plugins: [react()],
test: {
pool: 'threads',
- workspace: [
+ projects: [
{
// will inherit options from this config like plugins and pool
extends: true,
@@ -283,35 +298,21 @@ export default defineConfig({
},
})
```
-```ts [vitest.workspace.ts]
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- {
- extends: './vitest.config.ts',
- test: {
- name: 'unit',
- include: ['**/*.unit.test.ts'],
- },
- },
- {
- extends: './vitest.config.ts',
- test: {
- name: 'integration',
- include: ['**/*.integration.test.ts'],
- },
- },
-])
-```
-:::
::: danger Unsupported Options
某些配置选项不允许在项目配置中使用。其中最明显的是:
+<<<<<<< HEAD:guide/workspace.md
- `coverage`: 覆盖率是针对整个工作区进行的。
- `reporters`: 仅支持根级别的报告器。
- `resolveSnapshotPath`: 仅支持根级别的解析器。
- 所有其他不影响测试运行器的选项。
+=======
+- `coverage`: coverage is done for the whole process
+- `reporters`: only root-level reporters can be supported
+- `resolveSnapshotPath`: only root-level resolver is respected
+- all other options that don't affect test runners
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458:guide/projects.md
所有在项目配置中不支持的配置选项在 ["Config"](/config/) 指南中都会标记为 。这些选项必须在根配置文件中定义一次。
:::
diff --git a/guide/test-context.md b/guide/test-context.md
index 3f61ba60..88d1270b 100644
--- a/guide/test-context.md
+++ b/guide/test-context.md
@@ -14,19 +14,25 @@ outline: deep
```ts
import { it } from 'vitest'
+<<<<<<< HEAD
it('should work', (ctx) => {
// 打印测试的名称
console.log(ctx.task.name)
+=======
+it('should work', ({ task }) => {
+ // prints name of the test
+ console.log(task.name)
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
})
```
## 内置测试上下文
-#### `context.task`
+#### `task`
包含关于测试的元数据的只读对象。
-#### `context.expect`
+#### `expect`
绑定到当前测试的 `expect` API:
@@ -52,7 +58,12 @@ it.concurrent('math is hard', ({ expect }) => {
})
```
-#### `context.skip`
+#### `skip`
+
+```ts
+function skip(note?: string): never
+function skip(condition: boolean, note?: string): void
+```
跳过后续测试执行并将测试标记为已跳过:
@@ -65,7 +76,43 @@ it('math is hard', ({ skip }) => {
})
```
+<<<<<<< HEAD
## 扩展测试上下文
+=======
+Since Vitest 3.1, it accepts a boolean parameter to skip the test conditionally:
+
+```ts
+it('math is hard', ({ skip, mind }) => {
+ skip(mind === 'foggy')
+ expect(2 + 2).toBe(5)
+})
+```
+
+#### `context.signal` 3.2.0 {#context-signal}
+
+An [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that can be aborted by Vitest. The signal is aborted in these situations:
+
+- Test times out
+- User manually cancelled the test run with Ctrl+C
+- [`vitest.cancelCurrentRun`](/advanced/api/vitest#cancelcurrentrun) was called programmatically
+- Another test failed in parallel and the [`bail`](/config/#bail) flag is set
+
+```ts
+it('stop request when test times out', async ({ signal }) => {
+ await fetch('/resource', { signal })
+}, 2000)
+```
+
+#### `onTestFailed`
+
+The [`onTestFailed`](/api/#ontestfailed) hook bound to the current test. This API is useful if you are running tests concurrently and need to have a special handling only for this specific test.
+
+#### `onTestFinished`
+
+The [`onTestFinished`](/api/#ontestfailed) hook bound to the current test. This API is useful if you are running tests concurrently and need to have a special handling only for this specific test.
+
+## Extend Test Context
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
Vitest 提供了两种不同的方式来帮助你扩展测试上下文。
@@ -73,16 +120,24 @@ Vitest 提供了两种不同的方式来帮助你扩展测试上下文。
与 [Playwright](https://playwright.dev/docs/api/class-test#test-extend) 一样,你可以使用此方法通过自定义装置定义你自己的 `test` API,并在任何地方重复使用它。
+<<<<<<< HEAD
例如,我们首先使用两个固定装置创建 `myTest`,`todos` 和 `archive`。
+=======
+For example, we first create the `test` collector with two fixtures: `todos` and `archive`.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```ts [my-test.ts]
-import { test } from 'vitest'
+import { test as baseTest } from 'vitest'
const todos = []
const archive = []
+<<<<<<< HEAD
export const myTest = test.extend({
+=======
+export const test = baseTest.extend({
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
todos: async ({}, use) => {
// 在每次测试函数运行之前设置固定装置
todos.push(1, 2, 3)
@@ -101,16 +156,16 @@ export const myTest = test.extend({
```ts [my-test.test.ts]
import { expect } from 'vitest'
-import { myTest } from './my-test.js'
+import { test } from './my-test.js'
-myTest('add items to todos', ({ todos }) => {
+test('add items to todos', ({ todos }) => {
expect(todos.length).toBe(3)
todos.push(4)
expect(todos.length).toBe(4)
})
-myTest('move items from todos to archive', ({ todos, archive }) => {
+test('move items from todos to archive', ({ todos, archive }) => {
expect(todos.length).toBe(3)
expect(archive.length).toBe(0)
@@ -120,10 +175,16 @@ myTest('move items from todos to archive', ({ todos, archive }) => {
})
```
+<<<<<<< HEAD
我们还可以通过扩展 `myTest` 添加更多的固定装置或覆盖现有的固定装置。
+=======
+We can also add more fixtures or override existing fixtures by extending our `test`.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```ts
-export const myTest2 = myTest.extend({
+import { test as todosTest } from './my-test.js'
+
+export const test = todosTest.extend({
settings: {
// ...
},
@@ -135,8 +196,9 @@ export const myTest2 = myTest.extend({
Vitest 运行器将智能地初始化你的固定装置并根据使用情况将它们注入到测试上下文中。
```ts
-import { test } from 'vitest'
+import { test as baseTest } from 'vitest'
+<<<<<<< HEAD
async function todosFn({ task }, use) {
await use([1, 2, 3])
}
@@ -152,17 +214,35 @@ myTest('', ({ archive }) => {})
// todosFn 会运行
myTest('', ({ todos }) => {})
+=======
+const test = baseTest.extend<{
+ todos: number[]
+ archive: number[]
+}>({
+ todos: async ({ task }, use) => {
+ await use([1, 2, 3])
+ },
+ archive: []
+})
+
+// todos will not run
+test('skip', () => {})
+test('skip', ({ archive }) => {})
+
+// todos will run
+test('run', ({ todos }) => {})
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```
::: warning
在固定装置中使用 `test.extend()` 时,需要始终使用对象解构模式 `{ todos }` 来访问固定装置函数和测试函数中的上下文。
```ts
-myTest('context must be destructured', (context) => { // [!code --]
+test('context must be destructured', (context) => { // [!code --]
expect(context.todos.length).toBe(2)
})
-myTest('context must be destructured', ({ todos }) => { // [!code ++]
+test('context must be destructured', ({ todos }) => { // [!code ++]
expect(todos.length).toBe(2)
})
```
@@ -193,7 +273,7 @@ test('works correctly')
#### Default fixture
-Since Vitest 3, you can provide different values in different [projects](/guide/workspace). To enable this feature, pass down `{ injected: true }` to the options. If the key is not specified in the [project configuration](/config/#provide), then the default value will be used.
+Since Vitest 3, you can provide different values in different [projects](/guide/projects). To enable this feature, pass down `{ injected: true }` to the options. If the key is not specified in the [project configuration](/config/#provide), then the default value will be used.
:::code-group
```ts [fixtures.test.ts]
@@ -214,32 +294,36 @@ test('works correctly', ({ url }) => {
// url is "/empty" in "project-empty"
})
```
-```ts [vitest.workspace.ts]
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- {
- test: {
- name: 'project-new',
- },
- },
- {
- test: {
- name: 'project-full',
- provide: {
- url: '/full',
+```ts [vitest.config.ts]
+import { defineConfig } from 'vitest/config'
+
+export default defineConfig({
+ test: {
+ projects: [
+ {
+ test: {
+ name: 'project-new',
+ },
},
- },
- },
- {
- test: {
- name: 'project-empty',
- provide: {
- url: '/empty',
+ {
+ test: {
+ name: 'project-full',
+ provide: {
+ url: '/full',
+ },
+ },
},
- },
+ {
+ test: {
+ name: 'project-empty',
+ provide: {
+ url: '/empty',
+ },
+ },
+ },
+ ],
},
-])
+})
```
:::
@@ -317,20 +401,51 @@ interface MyFixtures {
archive: number[]
}
-const myTest = test.extend({
+const test = baseTest.extend({
todos: [],
archive: [],
})
-myTest('types are defined correctly', ({ todos, archive }) => {
+test('types are defined correctly', ({ todos, archive }) => {
expectTypeOf(todos).toEqualTypeOf()
expectTypeOf(archive).toEqualTypeOf()
})
```
+::: info Type Infering
+Note that Vitest doesn't support infering the types when the `use` function is called. It is always preferable to pass down the whole context type as the generic type when `test.extend` is called:
+
+```ts
+import { test as baseTest } from 'vitest'
+
+const test = baseTest.extend<{
+ todos: number[]
+ schema: string
+}>({
+ todos: ({ schema }, use) => use([]),
+ schema: 'test'
+})
+
+test('types are correct', ({
+ todos, // number[]
+ schema, // string
+}) => {
+ // ...
+})
+```
+:::
+
### `beforeEach` and `afterEach`
+<<<<<<< HEAD
每个测试的上下文都不同。 你可以在 `beforeEach` 和 `afterEach` hooks 中访问和扩展它们。
+=======
+::: danger Deprecated
+This is an outdated way of extending context and it will not work when the `test` is extended with `test.extend`.
+:::
+
+The contexts are different for each test. You can access and extend them within the `beforeEach` and `afterEach` hooks.
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```ts
import { beforeEach, it } from 'vitest'
@@ -347,7 +462,11 @@ it('should work', ({ foo }) => {
#### TypeScript
+<<<<<<< HEAD
你可以通过添加聚合(aggregate)类型 `TestContext`, 为你的自定义上下文属性提供类型支持。
+=======
+To provide property types for all your custom contexts, you can augment the `TestContext` type by adding
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
```ts
declare module 'vitest' {
diff --git a/guide/testing-types.md b/guide/testing-types.md
index 32bad889..a7744e58 100644
--- a/guide/testing-types.md
+++ b/guide/testing-types.md
@@ -97,7 +97,7 @@ expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: string }>()
const one = valueFromFunctionOne({ some: { complex: inputs } })
const two = valueFromFunctionTwo({ some: { other: inputs } })
-expectTypeOf(one).toEqualTypeof()
+expectTypeOf(one).toEqualTypeOf()
```
如果你发现很难使用 `expectTypeOf` API 并找出错误,你始终可以使用更简单的 `assertType` API:
diff --git a/package.json b/package.json
index 078b64b8..d03c1eff 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"vue": "latest"
},
"devDependencies": {
+<<<<<<< HEAD
"@antfu/eslint-config": "^4.10.1",
"@antfu/ni": "^24.3.0",
"@iconify-json/carbon": "latest",
@@ -30,6 +31,13 @@
"@types/fs-extra": "^11.0.4",
"@types/node": "^22.10.7",
"@unocss/reset": "latest",
+=======
+ "@iconify-json/carbon": "catalog:",
+ "@iconify-json/logos": "catalog:",
+ "@shikijs/transformers": "^3.4.2",
+ "@shikijs/vitepress-twoslash": "^3.4.2",
+ "@unocss/reset": "catalog:",
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
"@vite-pwa/assets-generator": "^0.2.6",
"@vite-pwa/vitepress": "^0.5.4",
"@vitejs/plugin-vue": "latest",
@@ -50,10 +58,16 @@
"unplugin-vue-components": "latest",
"vite": "^5.2.8",
"vite-plugin-pwa": "^0.21.2",
+<<<<<<< HEAD
"vitepress": "2.0.0-alpha.4",
"vitepress-plugin-group-icons": "^1.5.2",
"vitepress-plugin-tabs": "^0.7.0",
"vitest": "^3.0.2",
+=======
+ "vitepress": "2.0.0-alpha.5",
+ "vitepress-plugin-group-icons": "^1.5.5",
+ "vitepress-plugin-tabs": "^0.7.1",
+>>>>>>> e105a94261ac0c8ac3c84248eb73c73ce458c458
"workbox-window": "^7.3.0"
}
}