QA Vitest Writer
Purpose
Write Vitest unit and integration tests from test case specifications. Transform structured test cases (from qa-testcase-from-docs, qa-manual-test-designer, or specs) into executable Vitest code with proper mocking, fixtures, and assertions.
Trigger Phrases
- "Write Vitest tests for [module/feature]"
- "Generate Vitest unit tests from test cases"
- "Create Vitest integration tests"
- "Add Vitest tests for [spec/requirements]"
- "Migrate Jest tests to Vitest"
- "Vitest tests with mocks and fixtures"
- "In-source Vitest tests for [component]"
- "Parameterized Vitest tests (test.each)"
Key Advantages
| Advantage |
Description |
| ESM-native |
No CommonJS transformation; native import/export |
| Vite integration |
Uses Vite for fast transforms, HMR, and config |
| Watch mode |
Instant re-runs on file changes |
| Jest-compatible API |
describe/it/test, expect, vi (like jest) |
| In-source testing |
Co-locate tests with source (__tests__ or *.test.ts) |
| Workspace support |
Monorepo config with project-level overrides |
Workflow
- Read test cases — From specs, requirements, or manual test designs
- Analyze code — Inspect module under test: exports, dependencies, types
- Generate tests — Produce
describe/it blocks with assertions
- Add mocks/fixtures — Use
vi.mock, vi.fn, vi.spyOn, fixtures as needed
- Verify — Ensure tests run and pass; fix any config or import issues
Context7 MCP
Use Context7 MCP for current Vitest documentation when:
- API signatures or options are uncertain
- New Vitest features (e.g.,
vi.hoisted, workspace config) need verification
- Migration from Jest requires up-to-date compatibility notes
Key Patterns
| Pattern |
Usage |
describe / it / test |
Test structure (Jest-compatible) |
vi.mock() |
Module substitution; hoisted before imports |
vi.fn() |
Mock function with call tracking |
vi.spyOn() |
Spy on existing method; optionally replace |
vi.hoisted() |
Run code before imports (ESM mocking) |
| In-source testing |
__tests__/ or {module}.test.ts / {module}.spec.ts |
| Snapshot testing |
expect(obj).toMatchSnapshot() |
| Parameterized |
test.each([...]) / it.each([...]) |
| Concurrent |
it.concurrent / test.concurrent |
See references/patterns.md for detailed patterns.
Configuration
- Config file:
vitest.config.ts or vite.config.ts with test block
- Workspace:
vitest.workspace.ts for monorepos
- Coverage:
v8 or istanbul via @vitest/coverage-v8 / @vitest/coverage-istanbul
See references/config.md for configuration patterns.
Migration from Jest
| Jest |
Vitest |
Notes |
jest.mock() |
vi.mock() |
Same semantics; hoisted |
jest.fn() |
vi.fn() |
Same API |
jest.spyOn() |
vi.spyOn() |
Same API |
jest.useFakeTimers() |
vi.useFakeTimers() |
Same API |
beforeAll / afterAll |
Same |
Unchanged |
beforeEach / afterEach |
Same |
Unchanged |
ESM: Use vi.hoisted() when variables must be available in vi.mock factory. See references/best-practices.md.
File Naming
{module}.test.ts — Preferred for unit tests
{module}.spec.ts — Alternative; common for integration tests
__tests__/{module}.test.ts — Co-located in source directory
Scope
Can do (autonomous):
- Generate Vitest unit and integration tests from test cases
- Add mocks (
vi.mock, vi.fn, vi.spyOn), fixtures, and setup/teardown
- Use
test.each for parameterized tests; it.concurrent for parallel runs
- Configure
vitest.config.ts and coverage
- Migrate Jest tests to Vitest (syntax and API mapping)
- Call qa-diagram-generator for test flow diagrams if needed
Cannot do (requires confirmation):
- Change production code to satisfy tests
- Add tests for requirements not in source documents
- Override project-level Vitest/Vite config without approval
Will not do (out of scope):
- Execute tests (user runs
vitest or npm test)
- Write Playwright/Cypress E2E tests (use qa-playwright-ts-writer)
- Modify CI/CD pipelines
References
references/patterns.md — ESM mocking, in-source testing, concurrent tests, workspace
references/assertions.md — Vitest/Chai assertion reference
references/config.md — vitest.config.ts, coverage, workspace, plugins
references/best-practices.md — Best practices, Jest migration patterns
Quality Checklist
Troubleshooting
| Symptom |
Likely Cause |
Fix |
vi.mock not working |
ESM hoisting; variable not in scope |
Use vi.hoisted() to define variables before imports |
| Mock returns undefined |
Factory not returning correct shape |
Ensure factory returns object matching module exports |
| Tests pass individually, fail together |
Shared mutable state |
Reset mocks in beforeEach; use vi.clearAllMocks() |
import.meta.env wrong in tests |
Env not set for test |
Use vi.stubEnv() with unstubEnvs: true in config |
| Coverage not collected |
Reporter not configured |
Add @vitest/coverage-v8, set coverage.reporter |
| Slow test runs |
No workspace or wrong config |
Use vitest.workspace.ts; exclude node_modules |
| Type errors in mocks |
Mock shape doesn't match types |
Use vi.mocked() or type assertions; match export shape |
1---2name: qa-vitest-writer3description: Generate Vitest unit and integration tests for TypeScript projects with ESM-native support, Vite integration, and Jest-compatible API.4---56# QA Vitest Writer78## Purpose910Write Vitest unit and integration tests from test case specifications. Transform structured test cases (from qa-testcase-from-docs, qa-manual-test-designer, or specs) into executable Vitest code with proper mocking, fixtures, and assertions.1112## Trigger Phrases1314- "Write Vitest tests for [module/feature]"15- "Generate Vitest unit tests from test cases"16- "Create Vitest integration tests"17- "Add Vitest tests for [spec/requirements]"18- "Migrate Jest tests to Vitest"19- "Vitest tests with mocks and fixtures"20- "In-source Vitest tests for [component]"21- "Parameterized Vitest tests (test.each)"2223## Key Advantages2425| Advantage | Description |26| --------- | ----------- |27| **ESM-native** | No CommonJS transformation; native `import`/`export` |28| **Vite integration** | Uses Vite for fast transforms, HMR, and config |29| **Watch mode** | Instant re-runs on file changes |30| **Jest-compatible API** | `describe`/`it`/`test`, `expect`, `vi` (like `jest`) |31| **In-source testing** | Co-locate tests with source (`__tests__` or `*.test.ts`) |32| **Workspace support** | Monorepo config with project-level overrides |3334## Workflow35361. **Read test cases** — From specs, requirements, or manual test designs372. **Analyze code** — Inspect module under test: exports, dependencies, types383. **Generate tests** — Produce `describe`/`it` blocks with assertions394. **Add mocks/fixtures** — Use `vi.mock`, `vi.fn`, `vi.spyOn`, fixtures as needed405. **Verify** — Ensure tests run and pass; fix any config or import issues4142## Context7 MCP4344Use **Context7 MCP** for current Vitest documentation when:45- API signatures or options are uncertain46- New Vitest features (e.g., `vi.hoisted`, workspace config) need verification47- Migration from Jest requires up-to-date compatibility notes4849## Key Patterns5051| Pattern | Usage |52| ------- | ----- |53| `describe` / `it` / `test` | Test structure (Jest-compatible) |54| `vi.mock()` | Module substitution; hoisted before imports |55| `vi.fn()` | Mock function with call tracking |56| `vi.spyOn()` | Spy on existing method; optionally replace |57| `vi.hoisted()` | Run code before imports (ESM mocking) |58| In-source testing | `__tests__/` or `{module}.test.ts` / `{module}.spec.ts` |59| Snapshot testing | `expect(obj).toMatchSnapshot()` |60| Parameterized | `test.each([...])` / `it.each([...])` |61| Concurrent | `it.concurrent` / `test.concurrent` |6263See `references/patterns.md` for detailed patterns.6465## Configuration6667- **Config file:** `vitest.config.ts` or `vite.config.ts` with `test` block68- **Workspace:** `vitest.workspace.ts` for monorepos69- **Coverage:** `v8` or `istanbul` via `@vitest/coverage-v8` / `@vitest/coverage-istanbul`7071See `references/config.md` for configuration patterns.7273## Migration from Jest7475| Jest | Vitest | Notes |76| ---- | ------ | ----- |77| `jest.mock()` | `vi.mock()` | Same semantics; hoisted |78| `jest.fn()` | `vi.fn()` | Same API |79| `jest.spyOn()` | `vi.spyOn()` | Same API |80| `jest.useFakeTimers()` | `vi.useFakeTimers()` | Same API |81| `beforeAll` / `afterAll` | Same | Unchanged |82| `beforeEach` / `afterEach` | Same | Unchanged |8384ESM: Use `vi.hoisted()` when variables must be available in `vi.mock` factory. See `references/best-practices.md`.8586## File Naming8788- `{module}.test.ts` — Preferred for unit tests89- `{module}.spec.ts` — Alternative; common for integration tests90- `__tests__/{module}.test.ts` — Co-located in source directory9192## Scope9394**Can do (autonomous):**95- Generate Vitest unit and integration tests from test cases96- Add mocks (`vi.mock`, `vi.fn`, `vi.spyOn`), fixtures, and setup/teardown97- Use `test.each` for parameterized tests; `it.concurrent` for parallel runs98- Configure `vitest.config.ts` and coverage99- Migrate Jest tests to Vitest (syntax and API mapping)100- Call qa-diagram-generator for test flow diagrams if needed101102**Cannot do (requires confirmation):**103- Change production code to satisfy tests104- Add tests for requirements not in source documents105- Override project-level Vitest/Vite config without approval106107**Will not do (out of scope):**108- Execute tests (user runs `vitest` or `npm test`)109- Write Playwright/Cypress E2E tests (use qa-playwright-ts-writer)110- Modify CI/CD pipelines111112## References113114- `references/patterns.md` — ESM mocking, in-source testing, concurrent tests, workspace115- `references/assertions.md` — Vitest/Chai assertion reference116- `references/config.md` — vitest.config.ts, coverage, workspace, plugins117- `references/best-practices.md` — Best practices, Jest migration patterns118119## Quality Checklist120121- [ ] Tests match test case steps and expected results122- [ ] Mocks are properly scoped (per test or per describe)123- [ ] No hardcoded secrets or sensitive data124- [ ] Assertions are specific (avoid only `toBeTruthy` where value matters)125- [ ] `beforeEach`/`afterEach` restore state; mocks reset where needed126- [ ] File naming follows project convention (`*.test.ts` or `*.spec.ts`)127- [ ] Imports use ESM (`import`); no `require` unless required by dependency128- [ ] Coverage targets considered if specified in requirements129130## Troubleshooting131132| Symptom | Likely Cause | Fix |133| ------- | ------------ | --- |134| `vi.mock` not working | ESM hoisting; variable not in scope | Use `vi.hoisted()` to define variables before imports |135| Mock returns undefined | Factory not returning correct shape | Ensure factory returns object matching module exports |136| Tests pass individually, fail together | Shared mutable state | Reset mocks in `beforeEach`; use `vi.clearAllMocks()` |137| `import.meta.env` wrong in tests | Env not set for test | Use `vi.stubEnv()` with `unstubEnvs: true` in config |138| Coverage not collected | Reporter not configured | Add `@vitest/coverage-v8`, set `coverage.reporter` |139| Slow test runs | No workspace or wrong config | Use `vitest.workspace.ts`; exclude node_modules |140| Type errors in mocks | Mock shape doesn't match types | Use `vi.mocked()` or type assertions; match export shape |