Vitest Best Practices
When to Apply This Skill
Use this skill when you encounter any of these scenarios:
File Patterns
- Working with
*.test.ts, *.spec.ts, or similar test files
- Creating new test files for TypeScript/JavaScript modules
- Reviewing existing vitest test suites
User Intent Keywords
- User mentions: vitest, testing, TDD, BDD, unit tests, integration tests
- User asks to: write tests, add test coverage, fix failing tests, refactor tests
- User discusses: mocking, stubbing, assertions, test performance, test organization
Code Context
- Files importing from
vitest (describe, it, expect, vi)
- Test setup/teardown code (
beforeEach, afterEach, beforeAll, afterAll)
- Mock/spy implementations using
vi.mock(), vi.spyOn(), vi.fn()
- Assertion chains (
expect(...).toEqual(), .toBe(), .toThrow(), etc.)
Common Tasks
- Writing new test cases for existing functionality
- Refactoring tests for better clarity or performance
- Debugging flaky or failing tests
- Improving test coverage or maintainability
- Reviewing test code for best practices compliance
Do NOT Use This Skill When
- Working with Jest (not vitest) - different API and conventions
- Working with other testing frameworks (Mocha, Jasmine, etc.)
- Writing end-to-end tests with Playwright/Cypress (different scope)
- The task is purely about implementation code, not tests
What This Skill Covers
This skill provides comprehensive guidance on:
- Test Organization: File placement, naming conventions, grouping strategies
- AAA Pattern: Arrange, Act, Assert structure for clarity
- Parameterized Tests: Using
it.each() for testing variations
- Error Handling: Testing exceptions, edge cases, and fault injection
- Assertions: Choosing strict assertions (
toEqual, toStrictEqual, toThrow)
- Test Doubles: Fakes, stubs, mocks, spies - when to use each
- Async Testing: Promises, async/await, timers, and concurrent tests
- Performance: Fast tests, avoiding expensive operations, global cleanup configuration
- Vitest-Specific Features: Coverage, watch mode, benchmarking, type testing, setup files, discovering existing test configuration
- Snapshot Testing: When and how to use snapshots effectively
How to Use
This skill uses a progressive disclosure structure to minimize context usage:
1. Start with the Overview (AGENTS.md)
Read AGENTS.md for a concise overview of all rules with one-line summaries and the workflow for discovering existing test configuration.
2. Check for Existing Test Configuration
Before writing tests:
- First check
vitest.config.ts for global mock cleanup settings (clearMocks, resetMocks, restoreMocks)
- Then search for setup files (
test/setup.ts, vitest.setup.ts, etc.) and analyze their configuration
- See the workflow in AGENTS.md
3. Load Specific Rules as Needed
When you identify a relevant optimization, load the corresponding reference file for detailed implementation guidance:
Core Patterns:
- organization.md
- aaa-pattern.md
- parameterized-tests.md
- error-handling.md
- assertions.md
- test-doubles.md
Advanced Topics:
- async-testing.md
- performance.md
- vitest-features.md
- snapshot-testing.md
3. Apply the Pattern
Each reference file contains:
- ❌ Incorrect examples showing the anti-pattern
- ✅ Correct examples showing the optimal implementation
- Explanations of why the pattern matters
Quick Example
This skill helps you transform unclear tests into clear, maintainable ones:
Before (unclear):
test('product test', () => {
const p = new ProductService().add({name: 'Widget'});
expect(p.status).toBe('pendingApproval');
});
After (optimized with this skill):
describe('ProductService', () => {
describe('Add new product', () => {
it('should have status "pending approval" when no price is specified', () => {
// Arrange
const productService = new ProductService();
// Act
const newProduct = productService.add({name: 'Widget'});
// Assert
expect(newProduct.status).toEqual('pendingApproval');
});
});
});
Key Principles
- Clarity over cleverness: Tests should be instantly understandable
- Flat structure: Avoid deep nesting in describe blocks
- One assertion per concept: Focus tests on single behaviors
- Strict assertions: Prefer
toEqual over toBe, toStrictEqual when needed
- Minimal mocking: Use real implementations when practical
- Fast execution: Keep tests quick through efficient setup/teardown
- Configuration over repetition: Use
clearMocks: true in config instead of manual cleanup
- Discover before writing: Check vitest.config.ts and setup files before writing new tests
1---2name: vitest-best-practices3description: Comprehensive vitest testing patterns covering test structure, AAA pattern, parameterized tests, assertions, mocking, test doubles, error handling, async testing, and performance optimization. Use when writing, reviewing, or refactoring vitest tests, or when user mentions vitest, testing, TDD, test coverage, mocking, assertions, or test files (*.test.ts, *.spec.ts).4---5
6# Vitest Best Practices
7
8## When to Apply This Skill
9
10Use this skill when you encounter any of these scenarios:
11
12### File Patterns
13- Working with `*.test.ts`, `*.spec.ts`, or similar test files
14- Creating new test files for TypeScript/JavaScript modules
15- Reviewing existing vitest test suites
16
17### User Intent Keywords
18- User mentions: vitest, testing, TDD, BDD, unit tests, integration tests
19- User asks to: write tests, add test coverage, fix failing tests, refactor tests
20- User discusses: mocking, stubbing, assertions, test performance, test organization
21
22### Code Context
23- Files importing from `vitest` (`describe`, `it`, `expect`, `vi`)
24- Test setup/teardown code (`beforeEach`, `afterEach`, `beforeAll`, `afterAll`)
25- Mock/spy implementations using `vi.mock()`, `vi.spyOn()`, `vi.fn()`
26- Assertion chains (`expect(...).toEqual()`, `.toBe()`, `.toThrow()`, etc.)
27
28### Common Tasks
29- Writing new test cases for existing functionality
30- Refactoring tests for better clarity or performance
31- Debugging flaky or failing tests
32- Improving test coverage or maintainability
33- Reviewing test code for best practices compliance
34
35## Do NOT Use This Skill When
36
37- Working with Jest (not vitest) - different API and conventions
38- Working with other testing frameworks (Mocha, Jasmine, etc.)
39- Writing end-to-end tests with Playwright/Cypress (different scope)
40- The task is purely about implementation code, not tests
41
42## What This Skill Covers
43
44This skill provides comprehensive guidance on:
45
461. **Test Organization**: File placement, naming conventions, grouping strategies
472. **AAA Pattern**: Arrange, Act, Assert structure for clarity
483. **Parameterized Tests**: Using `it.each()` for testing variations
494. **Error Handling**: Testing exceptions, edge cases, and fault injection
505. **Assertions**: Choosing strict assertions (`toEqual`, `toStrictEqual`, `toThrow`)
516. **Test Doubles**: Fakes, stubs, mocks, spies - when to use each
527. **Async Testing**: Promises, async/await, timers, and concurrent tests
538. **Performance**: Fast tests, avoiding expensive operations, global cleanup configuration
549. **Vitest-Specific Features**: Coverage, watch mode, benchmarking, type testing, setup files, discovering existing test configuration
5510. **Snapshot Testing**: When and how to use snapshots effectively
56
57## How to Use
58
59This skill uses a **progressive disclosure** structure to minimize context usage:
60
61### 1. Start with the Overview (AGENTS.md)
62Read [AGENTS.md](AGENTS.md) for a concise overview of all rules with one-line summaries and the workflow for discovering existing test configuration.
63
64### 2. Check for Existing Test Configuration
65Before writing tests:
66- First check `vitest.config.ts` for global mock cleanup settings (`clearMocks`, `resetMocks`, `restoreMocks`)
67- Then search for setup files (`test/setup.ts`, `vitest.setup.ts`, etc.) and analyze their configuration
68- See the workflow in [AGENTS.md](AGENTS.md#workflow-before-writing-tests)
69
70### 3. Load Specific Rules as Needed
71When you identify a relevant optimization, load the corresponding reference file for detailed implementation guidance:
72
73**Core Patterns:**
74- [organization.md](references/organization.md)
75- [aaa-pattern.md](references/aaa-pattern.md)
76- [parameterized-tests.md](references/parameterized-tests.md)
77- [error-handling.md](references/error-handling.md)
78- [assertions.md](references/assertions.md)
79- [test-doubles.md](references/test-doubles.md)
80
81**Advanced Topics:**
82- [async-testing.md](references/async-testing.md)
83- [performance.md](references/performance.md)
84- [vitest-features.md](references/vitest-features.md)
85- [snapshot-testing.md](references/snapshot-testing.md)
86
87### 3. Apply the Pattern
88Each reference file contains:
89- ❌ Incorrect examples showing the anti-pattern
90- ✅ Correct examples showing the optimal implementation
91- Explanations of why the pattern matters
92
93## Quick Example
94
95This skill helps you transform unclear tests into clear, maintainable ones:
96
97**Before (unclear):**
98```ts
99test('product test', () => {
100 const p = new ProductService().add({name: 'Widget'});
101 expect(p.status).toBe('pendingApproval');
102});
103```
104
105**After (optimized with this skill):**
106```ts
107describe('ProductService', () => {
108 describe('Add new product', () => {
109 it('should have status "pending approval" when no price is specified', () => {
110 // Arrange
111 const productService = new ProductService();
112
113 // Act
114 const newProduct = productService.add({name: 'Widget'});
115
116 // Assert
117 expect(newProduct.status).toEqual('pendingApproval');
118 });
119 });
120});
121```
122
123## Key Principles
124
125- **Clarity over cleverness**: Tests should be instantly understandable
126- **Flat structure**: Avoid deep nesting in describe blocks
127- **One assertion per concept**: Focus tests on single behaviors
128- **Strict assertions**: Prefer `toEqual` over `toBe`, `toStrictEqual` when needed
129- **Minimal mocking**: Use real implementations when practical
130- **Fast execution**: Keep tests quick through efficient setup/teardown
131- **Configuration over repetition**: Use `clearMocks: true` in config instead of manual cleanup
132- **Discover before writing**: Check vitest.config.ts and setup files before writing new tests