vitest-testing
SKILL.md
Vitest Testing
Overview
Vitest is a Vite-native unit testing framework that shares the same configuration and plugin ecosystem. Built for speed with native ESM support, hot module replacement for tests, and parallel execution.
When to use: Unit tests, component tests, integration tests, hook tests, in-source tests. Testing React components with React Testing Library. Testing TanStack Query/Router/Form patterns.
When NOT to use: End-to-end testing (use Playwright), visual regression testing (use Percy/Chromatic), load testing (use k6).
Quick Reference
| Pattern | API | Key Points |
|---|---|---|
| Test structure | describe('suite', () => {}) |
Organize related tests |
| Single test | test('behavior', () => {}) or it() |
Both are aliases |
| Parameterized tests | test.each([...])('name', (arg) => {}) |
Run same test with different inputs |
| Concurrent tests | test.concurrent('name', async () => {}) |
Run tests in parallel |
| Skip test | test.skip('name', () => {}) or skipIf(cond) |
Conditionally skip tests |
| Only test | test.only('name', () => {}) |
Run specific test for debugging |
| Assertions | expect(value).toBe(expected) |
Compare primitive values |
| Deep equality | expect(obj).toEqual(expected) |
Compare objects/arrays |
| Async assertions | await expect(promise).resolves.toBe(value) |
Test promise resolution |
| Before each test | beforeEach(() => {}) |
Setup before each test |
| After each test | afterEach(() => {}) |
Cleanup after each test |
| Mock function | vi.fn() |
Create spy function |
| Mock module | vi.mock('./module') |
Replace entire module |
| Spy on method | vi.spyOn(obj, 'method') |
Track calls to existing method |
| Clear mocks | vi.clearAllMocks() |
Clear call history |
| Fake timers | vi.useFakeTimers() |
Control setTimeout/setInterval |
| Render component | render(<Component />) |
Mount React component for testing |
| Query by role | screen.getByRole('button') |
Find elements by accessibility role |
| User interaction | await user.click(element) |
Simulate user events |
| Wait for change | await waitFor(() => expect(...)) |
Wait for async changes |
| Find async element | await screen.findByText('text') |
Query + wait combined |
| Render hook | renderHook(() => useHook()) |
Test custom hooks |
| Update hook props | rerender(newProps) |
Re-render hook with new props |
| Snapshot | expect(value).toMatchSnapshot() |
Compare against saved snapshot |
| Inline snapshot | expect(value).toMatchInlineSnapshot() |
Snapshot stored in test file |
| CLI run once | vitest run |
Single run, no watch |
| Run changed tests | vitest --changed |
Tests affected by git changes |
| Filter by name | vitest -t "pattern" |
Grep test names |
| Soft assertions | expect.soft(value).toBe(x) |
Continue on failure, collect all |
| Poll assertions | await expect.poll(() => val).toBe(x) |
Retry until passing |
| Test fixtures | const test = base.extend<F>({...}) |
Reusable setup via test.extend |
| Hoisted mocks | vi.hoisted(() => ({ fn: vi.fn() })) |
Variables for vi.mock factory |
| Shard tests | vitest --shard 1/3 |
Split across CI workers |
| Tags | test('name', { tags: ['slow'] }, ...) |
Filter with --tags-filter |
| Stub globals | vi.stubGlobal('fetch', vi.fn()) |
Replace global objects cleanly |
Common Mistakes
| Mistake | Correct Pattern |
|---|---|
Using getBy for async content |
Use findBy or waitFor for async |
| Testing implementation details | Test behavior and public API |
Using getByTestId as first choice |
Prefer getByRole, getByLabelText, getByText |
Missing userEvent.setup() |
Always call const user = userEvent.setup() first |
| Shared state between tests | Use beforeEach to reset or create fresh instances |
| Not cleaning up mocks | Use vi.clearAllMocks() in afterEach |
| Mocking too much | Only mock external dependencies and APIs |
| Not disabling retries in tests | Set retry: false for TanStack Query tests |
| Immediate assertions on async | Use await waitFor() or findBy queries |
| Creating QueryClient in render | Create once in wrapper or use useState |
| Testing library code | Trust the library, test your usage |
| Not awaiting user events | All user.* methods return promises |
Using act manually |
userEvent and Testing Library handle this |
| Inline select without memoization | Extract to stable function for TanStack Query |
| Variables in vi.mock factory | Use vi.hoisted() to declare mock variables |
Single expect for multiple checks |
Use expect.soft() to collect all failures |
setTimeout in tests for async waits |
Use expect.poll() or vi.waitFor() |
Manual beforeEach for reusable setup |
Use test.extend fixtures for composable setup |
Delegation
- Test discovery: For finding untested code paths, use
Exploreagent - Coverage analysis: For full coverage review, use
Taskagent - E2E testing: If
playwrightskill is available, delegate E2E testing to it - Code review: After writing tests, delegate to
code-revieweragent
References
- Test fundamentals: structure, assertions, lifecycle hooks
- Mocking: vi.fn, vi.mock, vi.spyOn, module mocking
- Component testing: React Testing Library, queries, user-event
- Hook testing: renderHook, async hooks, TanStack patterns
- Test setup: jest-dom matchers, cleanup, custom render, MSW, polyfills
- Configuration: vitest.config.ts, workspace, coverage, reporters
- Advanced patterns: snapshots, concurrent tests, in-source, type testing
- CLI and filtering: commands, watch mode, tags, sharding
- Fixtures and context: test.extend, scoping, auto fixtures, injection
Weekly Installs
38
Repository
oakoss/agent-skillsGitHub Stars
4
First Seen
Feb 20, 2026
Security Audits
Installed on
claude-code36
opencode34
gemini-cli34
github-copilot34
amp34
codex34