Subchapter 13.19
references/features-test-tags.mdMarkdown4 KBView on GitHub
Tags label tests so you can filter what runs and apply shared options (timeout, retry) to a category of tests that span many files. Reach for tags over projects when the category needs different timeouts/retries (not different pools/environments).
Tags must be declared in config — using an undefined tag throws unless strictTags: false. Each tag can carry options applied to every test marked with it:
// vitest.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
tags: [
{ name: 'frontend', description: 'Frontend tests.' },
{ name: 'db', description: 'Database queries.', timeout: 60_000 },
{
name: 'flaky',
retry: process.env.CI ? 3 : 0,
timeout: 30_000,
priority: 1, // lower priority number wins on conflicts
},
],
strictTags: true, // default: error on unknown tags
},
})Type-safe tag names (augment TestTags, include the file in your tsconfig):
import 'vitest'
declare module 'vitest' {
interface TestTags {
tags: 'frontend' | 'backend' | 'db' | 'flaky'
}
}import { describe, test } from 'vitest'
test('renders homepage', { tags: ['frontend'] }, () => {})
// Tags inherit from the parent suite
describe('API endpoints', { tags: ['backend'] }, () => {
test('validates input', { tags: ['validation'] }, () => {
// has both "backend" (inherited) and "validation"
})
})Tag every test in a file with a JSDoc @module-tag at the top of the file (applies to all tests in the file, not just the next one):
/**
* @module-tag admin/pages/dashboard
*/
test('dashboard renders', () => {})When several tags set the same option on a test, priority wins first (lower number), then array order. Options on the test itself always win:
test('flaky db test', { tags: ['flaky', 'db'] }) // timeout 30_000 (flaky priority 1), retry 3
test('override', { tags: ['flaky', 'db'], timeout: 120_000 }) // timeout 120_000, retry 3Use --tagsFilter with an expression:
vitest --tagsFilter "frontend"
vitest --tagsFilter "db && !flaky"
vitest --tagsFilter "(unit || e2e) && !slow"
vitest --tagsFilter "api/*" # wildcard
vitest --list-tags # list defined tags (=json for JSON)Operators: and/&&, or/||, not/!, * wildcard, () grouping. Precedence: not > and > or. Multiple --tagsFilter flags combine with AND. Tag names can’t be and/or/not or contain special chars/spaces.
Programmatic: pass tagsFilter: ['frontend and backend'] to startVitest/createVitest.
Skip expensive setup when no matching tests are scheduled:
import { beforeAll, TestRunner } from 'vitest'
beforeAll(async () => {
if (TestRunner.matchesTags(['db'])) {
await seedDatabase()
}
})Returns true when the active --tagsFilter would include a test with those tags (or when no filter is active).
--tagsFilter (not --tags)@module-tag JSDoc commentsTestRunner.matchesTags gates expensive globalSetup/beforeAll work