Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
e6e834b
feat: support tags
sheremet-va Jan 16, 2026
c85fbba
fix: code to filter tags
sheremet-va Jan 16, 2026
d77b401
chore: fix filtering
sheremet-va Jan 16, 2026
07c13eb
docs: improve tags docs
sheremet-va Jan 16, 2026
072e115
docs: remove repeated example
sheremet-va Jan 16, 2026
972574d
docs: add tags to config
sheremet-va Jan 16, 2026
5adfef3
feat: support options inheritence
sheremet-va Jan 19, 2026
09e07e1
test: cleanup
sheremet-va Jan 19, 2026
bff0b23
feat: add --strict-tags option
sheremet-va Jan 19, 2026
dfd225b
feat: support @tag jsdoc
sheremet-va Jan 19, 2026
7f9df91
feat: support filter
sheremet-va Jan 19, 2026
9378016
refactor: rename to tagsFilter
sheremet-va Jan 19, 2026
6f1e45a
docs: cleanup
sheremet-va Jan 19, 2026
7dde3b8
docs: document options
sheremet-va Jan 19, 2026
d4a55de
docs: fix generator
sheremet-va Jan 19, 2026
feef1f9
chore: cleanup
sheremet-va Jan 19, 2026
b1c8bc1
chore: note
sheremet-va Jan 19, 2026
1882df2
docs: cleanup
sheremet-va Jan 19, 2026
fca2007
test: fix failing tests
sheremet-va Jan 19, 2026
c299640
refactor: rename @tag pragma to @module-tag
sheremet-va Jan 19, 2026
5fc1ebc
fix: support projects properly
sheremet-va Jan 19, 2026
68c78a5
docs: typos
sheremet-va Jan 19, 2026
86c1a36
test: add more tests
sheremet-va Jan 19, 2026
a18ee38
test: fix tests
sheremet-va Jan 19, 2026
9392799
test: remove only
sheremet-va Jan 19, 2026
124a649
fix: validate test tag names
sheremet-va Jan 19, 2026
c9d7e3d
chore: cleanup
sheremet-va Jan 20, 2026
25c0011
feat: add --list-tags
sheremet-va Jan 20, 2026
b9e2720
feat: support `--test-tags=json`
sheremet-va Jan 20, 2026
bcaba86
fix: support collecting tags statically
sheremet-va Jan 20, 2026
958a081
fixx(ui): expand nodes when searching
sheremet-va Jan 20, 2026
d42bb25
feat(ui): display tags as badges, support filtering
sheremet-va Jan 20, 2026
616ca0e
fix: pass down plugins
sheremet-va Jan 20, 2026
6855ce1
Merge branch 'main' of github.com:vitest-dev/vitest into feat/support…
sheremet-va Jan 20, 2026
43a9bf7
docs: add UI screenshots
sheremet-va Jan 20, 2026
3ccbd66
chore: fix colors
sheremet-va Jan 20, 2026
21510d2
chore: cleanup
sheremet-va Jan 20, 2026
3d59854
chore: lint
sheremet-va Jan 20, 2026
2cce331
docs: mention --list-tags in config
sheremet-va Jan 20, 2026
072214a
refactor: don't use ternaries
sheremet-va Jan 21, 2026
235fa9c
docs: review from raul
sheremet-va Jan 21, 2026
0f3d9b5
test: fix ui test
sheremet-va Jan 21, 2026
7b57c00
test(ui): add tags filter test
sheremet-va Jan 21, 2026
60cabb6
test(ui): check unknown tag
sheremet-va Jan 21, 2026
1995842
refactor: remove repetetive ode
sheremet-va Jan 21, 2026
1d59571
chore: tag -> tagsFilter, fix type
sheremet-va Jan 21, 2026
aab5e5f
docs: clarify
sheremet-va Jan 21, 2026
d1075ff
chore: review
sheremet-va Jan 22, 2026
b29ecf6
chore: cleanup
sheremet-va Jan 22, 2026
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
12 changes: 12 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,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 @@ -769,6 +777,10 @@ export default ({ mode }: { mode: string }) => {
text: 'Test Filtering',
link: '/guide/filtering',
},
{
text: 'Test Tags',
link: '/guide/test-tags',
},
{
text: 'Test Context',
link: '/guide/test-context',
Expand Down
2 changes: 2 additions & 0 deletions docs/.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 docs/api/advanced/test-case.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,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'
}
```

The options that test was collected with.

## 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 docs/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 @@ -82,6 +83,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 docs/api/advanced/test-suite.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,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
6 changes: 6 additions & 0 deletions docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,15 @@ interface TestOptions {
* @default 0
*/
repeats?: number
/**
* Custom tags of the test. Useful for filtering tests.
*/
tags?: string[] | string
}
```

<!-- 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.

::: tip
Expand Down
35 changes: 35 additions & 0 deletions docs/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 docs/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,
},
],
},
})
```
41 changes: 37 additions & 4 deletions docs/guide/cli-generated.md
Original file line number Diff line number Diff line change
Expand Up @@ -518,12 +518,26 @@ Default hook timeout in milliseconds (default: `10000`). Use `0` to disable time

Stop test execution when given number of tests have failed (default: `0`)

### retry
### retry.count

- **CLI:** `--retry <times>`
- **Config:** [retry](/config/retry)
- **CLI:** `--retry.count <times>`
- **Config:** [retry.count](/config/retry#retry-count)

Retry the test specific number of times if it fails (default: `0`)
Number of times to retry a test if it fails (default: `0`)

### retry.delay

- **CLI:** `--retry.delay <ms>`
- **Config:** [retry.delay](/config/retry#retry-delay)

Delay in milliseconds between retry attempts (default: `0`)

### retry.condition

- **CLI:** `--retry.condition <pattern>`
- **Config:** [retry.condition](/config/retry#retry-condition)

Regex pattern to match error messages that should trigger a retry. Only errors matching this pattern will cause a retry (default: retry on all errors)

### diff.aAnnotation

Expand Down Expand Up @@ -792,12 +806,31 @@ Use `bundle` to bundle the config with esbuild or `runner` (experimental) to pro

Start Vitest without running tests. Tests will be running only on change. This option is ignored when CLI file filters are passed. (default: `false`)

### listTags

- **CLI:** `--listTags [type]`

List all available tags instead of running tests. `--list-tags=json` will output tags in JSON format, unless there are no tags.

### clearCache

- **CLI:** `--clearCache`

Delete all Vitest caches, including `experimental.fsModuleCache`, without running any tests. This will reduce the performance in the subsequent test run.

### tagsFilter

- **CLI:** `--tagsFilter <expression>`

Run only tests with the specified tags. You can use logical operators `&&` (and), `||` (or) and `!` (not) to create complex expressions, see [Test Tags](/guide/test-tags#syntax) for more information.

### strictTags

- **CLI:** `--strictTags`
- **Config:** [strictTags](/config/stricttags)

Should Vitest throw an error if test has a tag that is not defined in the config. (default: `true`)

### experimental.fsModuleCache

- **CLI:** `--experimental.fsModuleCache`
Expand Down
Loading
Loading