vitest-testing · existential-birds — Claude Code skill: Vitest patterns
A skill that hands your coding agent a Vitest reference: assertions, mocks, async matchers, config. Useful when the project already runs on Vitest.
npx skills add existential-birds/beagle --skill vitest-testing -a claude-codeWhat vitest-testing does
The skill gives the agent a working reference for Vitest. Assertions are grouped by what you check: equality with toBe, toEqual and toStrictEqual, numbers with toBeCloseTo, strings and arrays with toMatch, toContain and toHaveLength, objects with toHaveProperty and toMatchObject, exceptions with toThrow.
Async gets its own section. The rule there is blunt: expect(...).resolves and expect(...).rejects always need await, otherwise the test passes for the wrong reason. Mocks are covered through vi.fn() and vi.mock — return values, mockResolvedValue, call assertions — with vi.clearAllMocks() in beforeEach as the cleanup habit. Test methods it.todo, it.skip, it.only, .concurrent and .each([...]) are listed in a table.
There is a verification sequence for when you add or change tests. First run the same command CI runs — check the package.json scripts, often vitest run — and confirm exit code 0 with no failures. Then scan every resolves and rejects line for a missing await. Three files under references/ go further: mocking, config, and patterns covering timers and snapshots. The advice assumes Vitest; swap in another runner and the guidance stops matching your setup.
What it helps with
- write a unit test for a function that awaits a network call
- set up
vitest.configand setup files - mock a module with
vi.mockand assert on its calls - catch a test that passes falsely because
awaitis missing - run the same case against several inputs with
.each([...])
Example prompts for the agent
- write Vitest tests for this module and mock
fetchDatawithvi.mock - check my tests: does every
expect(...).resolvesandrejectshaveawait? - add a parameterized test with
it.eachfor these three cases
How to install vitest-testing
1Skills CLI (Vercel)
npx skills add existential-birds/beagle --skill vitest-testing -a claude-code2Manually: put the files in place
~/.claude/skills/vitest-testing/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/vitest-testing/
1Skills CLI (Vercel)
npx skills add existential-birds/beagle --skill vitest-testing -a codex2Manually: put the files in place
.agents/skills/vitest-testing/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add existential-birds/beagle --skill vitest-testing -a cursor2Manually: put the files in place
.cursor/skills/vitest-testing/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install existential-birds/beagle vitest-testing2Manually: put the files in place
.github/skills/vitest-testing/SKILL.md1Skills CLI (Vercel)
npx skills add existential-birds/beagle --skill vitest-testing -a gemini-cli2Platform CLI
gemini skills install https://github.com/existential-birds/beagle --path plugins/beagle-react/skills/vitest-testingManually: put the files in place
.devin/skills/vitest-testing/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add existential-birds/beagle --skill vitest-testing -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about vitest-testing
How do I install vitest-testing in Claude?
Run npx skills add existential-birds/beagle --skill vitest-testing -a claude-code. The skill file lands at ~/.claude/skills/vitest-testing/SKILL.md.
What does vitest-testing do?
It feeds the agent a Vitest reference: assertions, async matchers, mocks via vi.fn and vi.mock, the it.skip and it.todo methods, plus a pass/fail checklist to run before committing tests.
What does the skill need to work?
A project running Vitest, since the test command comes from your package.json scripts. Under a different runner the guidance will not match.
Source text
SKILL.md · Apache-2.0
---
name: vitest-testing
description: Vitest testing framework patterns and best practices. Use when writing unit tests, integration tests, configuring vitest.config, mocking with vi.mock/vi.fn, using snapshots, or setting up test coverage. Triggers on describe, it, expect, vi.mock, vi.fn, beforeEach, afterEach, vitest.
---
# Vitest Best Practices
## Quick Reference
```ts
import { describe, it, expect, beforeEach, vi } from 'vitest'
describe('feature name', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('should do something specific', () => {
expect(actual).toBe(expected)
})
it.todo('planned test')
it.skip('temporarily disabled')
it.only('run only this during dev')
})
```
## Common Assertions
```ts
// Equality
expect(value).toBe(42) // Strict (===)
expect(obj).toEqual({ a: 1 }) // Deep equality
expect(obj).toStrictEqual({ a: 1 }) // Strict deep (checks types)
// Truthiness
expect(value).toBeTruthy()
expect(value).toBeFalsy()
expect(value).toBeNull()
expect(value).toBeUndefined()
// Numbers
expect(0.1 + 0.2).toBeCloseTo(0.3)
expect(value).toBeGreaterThan(5)
// Strings/Arrays
expect(str).toMatch(/pattern/)
expect(str).toContain('substring')
expect(array).toContain(item)
expect(array).toHaveLength(3)
// Objects
expect(obj).toHaveProperty('key')
expect(obj).toHaveProperty('nested.key', 'value')
expect(obj).toMatchObject({ subset: 'of properties' })
// Exceptions
expect(() => fn()).toThrow()
expect(() => fn()).toThrow('error message')
expect(() => fn()).toThrow(/pattern/)
```
## Async Testing
```ts
// Async/await (preferred)
it('fetches data', async () => {
const data = await fetchData()
expect(data).toEqual({ id: 1 })
})
// Promise matchers - ALWAYS await these
await expect(fetchData()).resolves.toEqual({ id: 1 })
await expect(fetchData()).rejects.toThrow('Error')
// Wrong - creates false positive
expect(promise).resolves.toBe(value) // Missing await!
```
## Quick Mock Reference
```ts
const mockFn = vi.fn()
mockFn.mockReturnValue(42)
mockFn.mockResolvedValue({ data: 'value' })
expect(mockFn).toHaveBeenCalled()
expect(mockFn).toHaveBeenCalledWith('arg1', 'arg2')
expect(mockFn).toHaveBeenCalledTimes(2)
```
## Verification gates
Use this sequence when you add or change tests; each step has an objective pass condition.
1. **Run the test suite** — From the package or workspace root, run the same command CI uses (check `package.json` scripts; often `vitest run`, `pnpm test`, or `npm test`). **Pass:** exit code is 0 and the report shows zero failing tests.
2. **Async matchers** — **Pass:** every `expect(…).resolves` and `expect(…).rejects` is prefixed with `await` (`await expect(...)`), as in [Async Testing](#async-testing). A line where `resolves` or `rejects` appears without `await` fails this gate.
## Additional Documentation
- **Mocking**: See [references/mocking.md](references/mocking.md) for module mocking, spying, cleanup
- **Configuration**: See [references/config.md](references/config.md) for vitest.config, setup files, coverage
- **Patterns**: See [references/patterns.md](references/patterns.md) for timers, snapshots, anti-patterns
## Test Methods Quick Reference
| Method | Purpose |
|--------|---------|
| `it()` / `test()` | Define test |
| `describe()` | Group tests |
| `beforeEach()` / `afterEach()` | Per-test hooks |
| `beforeAll()` / `afterAll()` | Per-suite hooks |
| `.skip` | Skip test/suite |
| `.only` | Run only this |
| `.todo` | Placeholder |
| `.concurrent` | Parallel execution |
| `.each([...])` | Parameterized tests |
© existential-birds · Apache-2.0 · existential-birds/beagle
Similar skills
All skills for Testing and QA →vitest-testing by other authors comes first.