Vitest testing framework conventions and practices. Invoke whenever task involves any interaction with Vitest — writing tests, configuring vitest.config.ts, mocking modules, debugging test failures, snapshots, coverage, or migrating from Jest.
Generates, configures, and debugs Vitest tests, including mocking, snapshots, coverage, and migration from Jest.
npx claudepluginhub xobotyi/cc-foundryThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/assertions.mdreferences/configuration.mdreferences/coverage.mdreferences/jest-migration.mdreferences/lifecycle.mdreferences/mocking.mdTest behavior, not implementation. Mock boundaries, not internals.
Vitest is a Vite-native test framework with Jest-compatible APIs. It shares your app's Vite config (aliases, plugins, transforms) so tests run against the same code you ship.
| Topic | Reference | Contents |
|---|---|---|
| Mocking | references/mocking.md | Full mocking rules, module mocking patterns, cleanup strategy |
| Assertions | references/assertions.md | Matcher tables, asymmetric matchers, soft assertions |
| Lifecycle | references/lifecycle.md | Hook execution order, test context, setup files, global setup |
| Configuration | references/configuration.md | Config file options, projects, pools, sharding, env vars |
| Coverage | references/coverage.md | Coverage providers, thresholds, ignore comments, performance |
| Jest migration | references/jest-migration.md | Jest API translation, key behavioral differences, Mocha/Sinon |
import { describe, it, expect, vi } from 'vitest' — do not
rely on globals unless the project has globals: true configured.'returns empty array when input is null', not 'test case 1'.describe for grouping. Group by unit (function, class, component), not by
test type.it over test. Both work, but it reads better inside describe:
describe('parseUrl', () => { it('extracts hostname', ...) }).it.each / describe.each for parametrized tests. Supports array form and
template literal form with $key interpolation.it.skip, it.only, it.todo, it.fails, it.skipIf(cond),
it.runIf(cond).it('name', { retry: 3 }, fn). Repeat: it('name', { repeats: 100 }, fn).describe.concurrent(...) — use expect from test context
(destructured parameter) for correct snapshot/assertion tracking.vi.fn() creates a standalone trackable mock. Optionally accepts implementation.vi.spyOn(obj, 'method') wraps existing method while preserving original. Also
supports vi.spyOn(obj, 'prop', 'get') for getters/setters.vi.spyOn over vi.mock when you only need to observe or override a
single export.vi.mock() is hoisted. It moves to top of file regardless of where you write it.
Always runs before imports.default
key: vi.mock('./mod', () => ({ default: val, namedExport: vi.fn() })).importOriginal:
vi.mock(import('./api'), async (importOriginal) => ({ ...await importOriginal(), fetchUser: vi.fn() })).vi.doMock() is not hoisted — runs at position. Only affects subsequent dynamic
import() calls. Use when you need per-test mock behavior.vi.mock cannot intercept internal calls. If foo() calls bar() in the same
file, mocking bar externally does not affect foo. Refactor to separate modules or
use dependency injection.restoreMocks: true in config (recommended) or
afterEach(() => vi.restoreAllMocks()).vi.useFakeTimers() with vi.useRealTimers() — in beforeEach/afterEach
or use fakeTimers config option.vi.mocked(fn) narrows TypeScript types to mock types without runtime changes.Full mocking rules (auto-mocking, spy mode, vi.hoisted, __mocks__ directory, env/globals
stubbing, async helpers): see references/mocking.md.
| Matcher | Use When |
|---|---|
toBe(val) | Primitives or same reference (Object.is) |
toEqual(val) | Deep structural equality (ignores undefined in expected) |
toStrictEqual(val) | Deep equality + checks undefined keys, sparse arrays, class types |
toMatchObject(subset) | Object contains at least these properties |
expect(() => throwingFn()).toThrow('message').await expect(asyncFn()).rejects.toThrow('message').await async assertions. await expect(promise).resolves.toEqual(...) — an
un-awaited assertion silently passes.expect.poll(() => value, { timeout, interval }) — retries assertion until pass or
timeout. Prefer over manual waitFor loops.expect.soft(val) continues after failure, reports all errors at end.toEqual, toHaveBeenCalledWith: expect.any(Number),
expect.arrayContaining([...]), expect.objectContaining({}),
expect.stringMatching(/regex/). Negate with expect.not.*.expect.assertions(n) — exactly n assertions must run.
expect.hasAssertions() — at least one. Guard against missing assertions in
async code.Truthiness, number, string/array/object matchers, type checks, spy assertions, custom
error messages, expect.unreachable: see references/assertions.md.
expect(val).toMatchSnapshot() — writes to .snap file.expect(val).toMatchInlineSnapshot(\"expected"`)` — Vitest
auto-updates the string argument.toMatchSnapshot({ id: expect.any(String) }).
Never snapshot timestamps, random IDs, or other volatile data without matchers.vitest -u or press u in watch mode.beforeAll/afterAll run once per describe block (or per file at top level).beforeEach/afterEach run before/after every test in current scope.beforeAll or beforeEach returns a function, it
runs as teardown. Vitest-specific, not in Jest. Be careful not to accidentally
return values — wrap in braces: beforeEach(() => { setupFn() }).onTestFinished(fn) — register cleanup inside a test. Always runs regardless of
pass/fail.onTestFailed(fn) — runs only on failure. Useful for diagnostics.setupFiles: ['./test/setup.ts'] — runs before each test file in the same process.
Use for global hooks, custom matchers, shared setup.globalSetup: ['./test/global-setup.ts'] — runs once before any test workers.
Use for expensive one-time setup (database seeding, server startup). Return a function
for teardown.Hook execution order, test context, hook order config, provide/inject, and
global vs setup file comparison: see references/lifecycle.md.
vitest.config.ts with defineConfig from 'vitest/config'. Inherits Vite
plugins and aliases automatically.vite.config.ts, add /// <reference types="vitest/config" /> directive.projects (v3.2+, replaces deprecated workspace) for multi-environment setups.
Every project must have a unique name.Config file merging, key options table, pools and parallelism, environment variables,
in-source testing, and sharding: see references/configuration.md.
Set coverage.include to catch uncovered files. Use v8 provider (default, recommended).
Set thresholds in config. Run coverage only in CI, not in watch mode.
Provider comparison, reporters, ignore comments, and performance tips:
see references/coverage.md.
Define via expect.extend({ matcherName(received, ...args) {} }). Return { pass, message }.
Add TypeScript declarations via interface Matchers<T> in vitest.d.ts.
Matcher context, TypeScript setup, and diff output: see references/assertions.md.
Replace jest.* with vi.*. Key differences: mock factory must return object with
explicit exports, mockReset restores original impl, auto-mocking requires explicit
vi.mock() call, hook return values are teardown functions.
Full API translation table, behavioral differences, and Mocha/Sinon migration:
see references/jest-migration.md.
When writing tests:
When reviewing tests:
The javascript skill governs language choices; this skill governs Vitest testing decisions. Activate the relevant runtime skill (nodejs or bun) for runtime-specific behavior.
Test behavior, not implementation. When in doubt, mock less.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.