Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,14 @@ export default ({ mode }: { mode: string }) => {
text: 'sequence',
link: '/config/sequence',
},
{
text: 'tags',
link: '/config/tags',
},
{
text: 'strictTags',
link: '/config/stricttags',
},
{
text: 'typecheck',
link: '/config/typecheck',
Expand Down Expand Up @@ -773,7 +781,15 @@ export default ({ mode }: { mode: string }) => {
link: '/guide/filtering',
},
{
<<<<<<< HEAD
text: '测试上下文',
=======
text: 'Test Tags',
link: '/guide/test-tags',
},
{
text: 'Test Context',
>>>>>>> 4a24a6d9f32c7ad524eb2a1d042d5ee52ed4312b
link: '/guide/test-context',
},
{
Expand Down
2 changes: 2 additions & 0 deletions .vitepress/scripts/cli-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const skipConfig = new Set([
'browser.name',
'browser.fileParallelism',
'clearCache',
'tagsFilter',
'listTags',
])

function resolveOptions(options: CLIOptions<any>, parentName?: string) {
Expand Down
6 changes: 6 additions & 0 deletions api/advanced/test-case.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,18 @@ interface TaskOptions {
readonly shuffle: boolean | undefined
readonly retry: number | undefined
readonly repeats: number | undefined
readonly tags: string[] | undefined
readonly timeout: number | undefined
readonly mode: 'run' | 'only' | 'skip' | 'todo'
}
```

收集测试时使用的选项。

## tags <Version>4.1.0</Version> {#tags}

[Tags](/guide/test-tags) that were implicitly or explicitly assigned to the test.

## ok

```ts
Expand Down
5 changes: 5 additions & 0 deletions api/advanced/test-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const specification = project.createSpecification(
testLines: [20, 40],
testNamePattern: /hello world/,
testIds: ['1223128da3_0_0_0', '1223128da3_0_0'],
testTagsFilter: ['frontend and backend'],
} // optional test filters
)
```
Expand Down Expand Up @@ -84,6 +85,10 @@ A regexp that matches the name of the test in this module. This value will overr

The ids of tasks inside of this specification to run.

## testTagsFilter <Version>4.1.0</Version> {#testtagsfilter}

The [tags filter](/guide/test-tags#syntax) that a test must pass in order to be included in the run. Multiple filters are treated as `AND`.

## toJSON

```ts
Expand Down
1 change: 1 addition & 0 deletions api/advanced/test-suite.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ interface TaskOptions {
readonly shuffle: boolean | undefined
readonly retry: number | undefined
readonly repeats: number | undefined
readonly tags: string[] | undefined
readonly mode: 'run' | 'only' | 'skip' | 'todo'
}
```
Expand Down
10 changes: 10 additions & 0 deletions api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,20 @@ interface TestOptions {
* @default 0
*/
repeats?: number
/**
* Custom tags of the test. Useful for filtering tests.
*/
tags?: string[] | string
}
```

<<<<<<< HEAD
当测试函数返回一个 promise 时,运行器会等待它解析结束收集异步的结果。如果 promise 被拒绝,测试就会失败。
=======
<!-- TODO: rewrite this into separate test files with options highlighted -->

When a test function returns a promise, the runner will wait until it is resolved to collect async expectations. If the promise is rejected, the test will fail.
>>>>>>> 4a24a6d9f32c7ad524eb2a1d042d5ee52ed4312b

::: tip
在 Jest 中,`TestFunction` 也可以是 `(done: DoneCallback) => void` 类型。如果使用这种形式,测试将在调用 `done` 之前不会结束。也可以使用 `async` 函数来实现相同的效果,请参阅 [迁移指南中的回调完成部分](/guide/migration.html#done-callback)。
Expand Down
15 changes: 15 additions & 0 deletions api/vi.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,11 @@ function mocked<T>(

TypeScript 的类型助手。只返回传入的对象。

<<<<<<< HEAD
当 `partial` 为 `true` 时,它将期望一个 `Partial<T>` 作为返回值。默认情况下,这只会让 TypeScript 认为第一层的值是模拟的。我们可以将 `{ deep: true }` 作为第二个参数传递给 TypeScript,告诉它整个对象都是模拟的(如果实际上是的话)。
=======
When `partial` is `true` it will expect a `Partial<T>` as a return value. By default, this will only make TypeScript believe that the first level values are mocked. You can pass down `{ deep: true }` as a second argument to tell TypeScript that the whole object is mocked, if it actually is. You can pass down `{ partial: true, deep: true }` to make nested objects also partial recursively.
>>>>>>> 4a24a6d9f32c7ad524eb2a1d042d5ee52ed4312b

```ts [example.ts]
export function add(x: number, y: number): number {
Expand All @@ -267,6 +271,10 @@ export function add(x: number, y: number): number {
export function fetchSomething(): Promise<Response> {
return fetch('https://vitest.dev/')
}

export function getUser(): { name: string; address: { city: string; zip: string } } {
return { name: 'John', address: { city: 'New York', zip: '10001' } }
}
```

```ts [example.test.ts]
Expand All @@ -286,6 +294,13 @@ test('mock return value with only partially correct typing', async () => {
})
// vi.mocked(example.someFn).mockResolvedValue({ ok: false }) // 这是一个错误类型
})

test('mock return value with deep partial typing', async () => {
vi.mocked(example.getUser, { partial: true, deep: true }).mockReturnValue({
address: { city: 'Los Angeles' },
})
expect(example.getUser().address.city).toBe('Los Angeles')
})
```

### vi.importActual
Expand Down
35 changes: 35 additions & 0 deletions config/stricttags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: strictTags | Config
outline: deep
---

# strictTags <Version>4.1.0</Version> {#stricttags}

- **Type:** `boolean`
- **Default:** `true`
- **CLI:** `--strict-tags`, `--no-strict-tags`

Should Vitest throw an error if test has a [`tag`](/config/tags) that is not defined in the config to avoid silently doing something surprising due to mistyped names (applying the wrong configuration or skipping the test due to a `--tags-filter` flag).

Note that Vitest will always throw an error if `--tags-filter` flag defines a tag not present in the config.

For example, this test will throw an error because the tag `fortnend` has a typo (it should be `frontend`):

::: code-group
```js [form.test.js]
test('renders a form', { tags: ['fortnend'] }, () => {
// ...
})
```
```js [vitest.config.js]
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
tags: [
{ name: 'frontend' },
],
},
})
```
:::
194 changes: 194 additions & 0 deletions config/tags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
---
title: tags | Config
outline: deep
---

# tags <Version>4.1.0</Version> {#tags}

- **Type:** `TestTagDefinition[]`
- **Default:** `[]`

Defines all [available tags](/guide/test-tags) in your test project. By default, if test defines a name not listed here, Vitest will throw an error, but this can be configured via a [`strictTags`](/config/stricttags) option.

If you are using [`projects`](/config/projects), they will inherit all global tags definitions automatically.

Use [`--tags-filter`](/guide/test-tags#syntax) to filter tests by their tags. Use [`--list-tags`](/guide/cli#listtags) to print every tag in your Vitest workspace.

## name

- **Type:** `string`
- **Required:** `true`

The name of the tag. This is what you use in the `tags` option in tests.

```ts
export default defineConfig({
test: {
tags: [
{ name: 'unit' },
{ name: 'e2e' },
],
},
})
```

::: tip
If you are using TypeScript, you can enforce what tags are available by augmenting the `TestTags` type with a property that contains a union of strings (make sure this file is included by your `tsconfig`):

```ts [vitest.shims.ts]
import 'vitest'

declare module 'vitest' {
interface TestTags {
tags:
| 'frontend'
| 'backend'
| 'db'
| 'flaky'
}
}
```
:::

## description

- **Type:** `string`

A human-readable description for the tag. This will be shown in UI and inside error messages when a tag is not found.

```ts
export default defineConfig({
test: {
tags: [
{
name: 'slow',
description: 'Tests that take a long time to run.',
},
],
},
})
```

## priority

- **Type:** `number`
- **Default:** `Infinity`

Priority for merging options when multiple tags with the same options are applied to a test. Lower number means higher priority (e.g., priority `1` takes precedence over priority `3`).

```ts
export default defineConfig({
test: {
tags: [
{
name: 'flaky',
timeout: 30_000,
priority: 1, // higher priority
},
{
name: 'db',
timeout: 60_000,
priority: 2, // lower priority
},
],
},
})
```

When a test has both tags, the `timeout` will be `30_000` because `flaky` has a higher priority.

## Test Options

Tags can define test options that will be applied to every test marked with the tag. These options are merged with the test's own options, with the test's options taking precedence.

### timeout

- **Type:** `number`

Test timeout in milliseconds.

### retry

- **Type:** `number | { count?: number, delay?: number, condition?: RegExp }`

Retry configuration for the test. If a number, specifies how many times to retry. If an object, allows fine-grained retry control.

### repeats

- **Type:** `number`

How many times the test will run again.

### concurrent

- **Type:** `boolean`

Whether suites and tests run concurrently.

### sequential

- **Type:** `boolean`

Whether tests run sequentially.

### skip

- **Type:** `boolean`

Whether the test should be skipped.

### only

- **Type:** `boolean`

Should this test be the only one running in a suite.

### todo

- **Type:** `boolean`

Whether the test should be skipped and marked as a todo.

### fails

- **Type:** `boolean`

Whether the test is expected to fail. If it does, the test will pass, otherwise it will fail.

## Example

```ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
tags: [
{
name: 'unit',
description: 'Unit tests.',
},
{
name: 'e2e',
description: 'End-to-end tests.',
timeout: 60_000,
},
{
name: 'flaky',
description: 'Flaky tests that need retries.',
retry: process.env.CI ? 3 : 0,
priority: 1,
},
{
name: 'slow',
description: 'Slow tests.',
timeout: 120_000,
},
{
name: 'skip-ci',
description: 'Tests to skip in CI.',
skip: !!process.env.CI,
},
],
},
})
```
Loading
Loading