Files
agent-skills/skills/vitest/references/core-test-api.md
Jason Woltje f5792c40be feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories:
- anthropics/skills: 16 (docs, design, MCP, testing)
- obra/superpowers: 14 (TDD, debugging, agents, planning)
- coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth)
- better-auth/skills: 5 (auth patterns)
- vercel-labs/agent-skills: 5 (React, design, Vercel)
- antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo)
- Plus 13 individual skills from various repos

Mosaic Stack is not limited to coding — the Orchestrator and
subagents serve coding, business, design, marketing, writing,
logistics, analysis, and more.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:27:42 -06:00

234 lines
3.9 KiB
Markdown

---
name: test-api
description: test/it function for defining tests with modifiers
---
# Test API
## Basic Test
```ts
import { expect, test } from 'vitest'
test('adds numbers', () => {
expect(1 + 1).toBe(2)
})
// Alias: it
import { it } from 'vitest'
it('works the same', () => {
expect(true).toBe(true)
})
```
## Async Tests
```ts
test('async test', async () => {
const result = await fetchData()
expect(result).toBeDefined()
})
// Promises are automatically awaited
test('returns promise', () => {
return fetchData().then(result => {
expect(result).toBeDefined()
})
})
```
## Test Options
```ts
// Timeout (default: 5000ms)
test('slow test', async () => {
// ...
}, 10_000)
// Or with options object
test('with options', { timeout: 10_000, retry: 2 }, async () => {
// ...
})
```
## Test Modifiers
### Skip Tests
```ts
test.skip('skipped test', () => {
// Won't run
})
// Conditional skip
test.skipIf(process.env.CI)('not in CI', () => {})
test.runIf(process.env.CI)('only in CI', () => {})
// Dynamic skip via context
test('dynamic skip', ({ skip }) => {
skip(someCondition, 'reason')
// ...
})
```
### Focus Tests
```ts
test.only('only this runs', () => {
// Other tests in file are skipped
})
```
### Todo Tests
```ts
test.todo('implement later')
test.todo('with body', () => {
// Not run, shows in report
})
```
### Failing Tests
```ts
test.fails('expected to fail', () => {
expect(1).toBe(2) // Test passes because assertion fails
})
```
### Concurrent Tests
```ts
// Run tests in parallel
test.concurrent('test 1', async ({ expect }) => {
// Use context.expect for concurrent tests
expect(await fetch1()).toBe('result')
})
test.concurrent('test 2', async ({ expect }) => {
expect(await fetch2()).toBe('result')
})
```
### Sequential Tests
```ts
// Force sequential in concurrent context
test.sequential('must run alone', async () => {})
```
## Parameterized Tests
### test.each
```ts
test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) = %i', (a, b, expected) => {
expect(a + b).toBe(expected)
})
// With objects
test.each([
{ a: 1, b: 1, expected: 2 },
{ a: 1, b: 2, expected: 3 },
])('add($a, $b) = $expected', ({ a, b, expected }) => {
expect(a + b).toBe(expected)
})
// Template literal
test.each`
a | b | expected
${1} | ${1} | ${2}
${1} | ${2} | ${3}
`('add($a, $b) = $expected', ({ a, b, expected }) => {
expect(a + b).toBe(expected)
})
```
### test.for
Preferred over `.each` - doesn't spread arrays:
```ts
test.for([
[1, 1, 2],
[1, 2, 3],
])('add(%i, %i) = %i', ([a, b, expected], { expect }) => {
// Second arg is TestContext
expect(a + b).toBe(expected)
})
```
## Test Context
First argument provides context utilities:
```ts
test('with context', ({ expect, skip, task }) => {
console.log(task.name) // Test name
skip(someCondition) // Skip dynamically
expect(1).toBe(1) // Context-bound expect
})
```
## Custom Test with Fixtures
```ts
import { test as base } from 'vitest'
const test = base.extend({
db: async ({}, use) => {
const db = await createDb()
await use(db)
await db.close()
},
})
test('query', async ({ db }) => {
const users = await db.query('SELECT * FROM users')
expect(users).toBeDefined()
})
```
## Retry Configuration
```ts
test('flaky test', { retry: 3 }, async () => {
// Retries up to 3 times on failure
})
// Advanced retry options
test('with delay', {
retry: {
count: 3,
delay: 1000,
condition: /timeout/i, // Only retry on timeout errors
},
}, async () => {})
```
## Tags
```ts
test('database test', { tags: ['db', 'slow'] }, async () => {})
// Run with: vitest --tags db
```
## Key Points
- Tests with no body are marked as `todo`
- `test.only` throws in CI unless `allowOnly: true`
- Use context's `expect` for concurrent tests and snapshots
- Function name is used as test name if passed as first arg
<!--
Source references:
- https://vitest.dev/api/test.html
-->