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
-
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, cleanup patterns
-
Vitest-Specific Features: Coverage, watch mode, benchmarking, type testing, setup files
-
Snapshot Testing: When and how to use snapshots effectively
How to Use
This skill uses a progressive disclosure structure to minimize context usage:
- Start with the Overview (AGENTS.md)
Read AGENTS.md for a concise overview of all rules with one-line summaries.
- 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
- 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