# Testing Vitest

> Vitest unit and component testing conventions — Testing Library, mocking policy, MSW, timers. Use when writing or fixing unit/component tests or vitest config. 日本語の依頼例:「ユニットテスト書いて」「Vitest」「テスト追加して」「モック」「ロジックのテスト」。

- **Type:** Skill
- **Install:** `agentstack add skill-syo-m-fable5-skills-testing-vitest`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [Syo-M](https://agentstack.voostack.com/s/syo-m)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Syo-M](https://github.com/Syo-M)
- **Source:** https://github.com/Syo-M/fable5_skills/tree/main/plugin/skills/testing-vitest

## Install

```sh
agentstack add skill-syo-m-fable5-skills-testing-vitest
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Vitest

## What to test, where

- Pure logic (utils, reducers, schema transforms) → plain unit tests. Fast, no DOM.
- Component behavior → Storybook play functions are the primary component-test layer (see `storybook` skill); write direct Testing Library tests only for headless hooks/providers with no visual states, or when exhaustively covering a pure prop/branch matrix (roughly ≥ 6 combinations) where one story per case would bloat the catalog — the meaningful visual states still get stories.
- Full user flows → Playwright (see `testing-playwright`). Don't simulate routing/auth flows in jsdom.

Worked examples (the layer decision people get wrong most):
- "Test that the Button shows a spinner while submitting" → Storybook play function — a visible state + interaction the catalog should own; not a Vitest component test.
- "Test that `formatCurrency` rounds half-up and handles -0" → Vitest unit test — pure logic, no DOM, no story.
- "Test the `useDebounce` hook's timing" → Vitest unit test with fake timers — headless hook, no visual state.
- "Test the checkout form across 8 field-validation combinations" → Vitest for the exhaustive matrix, plus one story per *meaningful* visual state (empty / error / submitting) — don't make 8 stories.
- Test behavior users observe, not implementation: no asserting on state internals, no `container.querySelector('.styles_button_x')`, no spying on internal functions of the unit under test.

## Structure

- Colocate: `format.ts` + `format.test.ts`. Name tests as behavior sentences: `it('disables submit while the request is in flight')`.
- Arrange–Act–Assert, one behavior per test. Shared setup in a plain `setup()` factory function returning what tests need — avoid sprawling `beforeEach` mutation.
- No logic in tests (if/loops computing expectations). Expected values are literals.

## Testing Library rules

- Query priority (same list as `testing-playwright`): `getByRole` (with `name`) > `getByLabelText` > `getByText` > `getByTestId` (last resort, added deliberately). Never query by placeholder — a placeholder is not a label (see `a11y`); needing it means the input lacks one.
- All interactions via `userEvent` (`const user = userEvent.setup()`), never `fireEvent` — userEvent fires the full real event sequence.
- Async UI: `await screen.findByRole(...)` / `waitFor` for assertions only — never `waitFor` containing a user action, never arbitrary `setTimeout` sleeps.
- Wrap components needing providers with a shared `renderWithProviders` test util — one definition, not per-file copies.

## Mocking policy — mock at the boundary, not the module graph

- Network: **MSW** handlers, not `vi.mock`-ing your own fetch wrapper. Tests then survive refactors of the data layer.
- `vi.mock` only for true externals (analytics SDK, payment widget) and module-level non-determinism. If you're mocking your own module to make a test pass, the design or the test level is wrong.
- Non-determinism: `vi.useFakeTimers()` + `vi.setSystemTime()` for time; always `vi.useRealTimers()` in `afterEach`. With fake timers + userEvent, configure `advanceTimers: vi.advanceTimersByTime`.
- `vi.restoreAllMocks()` in `afterEach` (or `restoreMocks: true` in config) — leaked mocks cause order-dependent flake.

## Config

- Single source: define `test` in `vite.config.ts` (or merge it) so aliases/plugins match the app. `environment: 'jsdom'` only for DOM test projects; pure-logic tests run in `node` (faster) — use Vitest projects to split.
- Coverage is a signal, not a goal: review uncovered branches, don't chase a number with assertion-free tests.
- A test that fails intermittently is a bug to fix now (usually unawaited async or shared state) — never retry-loop or skip it.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Syo-M](https://github.com/Syo-M)
- **Source:** [Syo-M/fable5_skills](https://github.com/Syo-M/fable5_skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-syo-m-fable5-skills-testing-vitest
- Seller: https://agentstack.voostack.com/s/syo-m
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
