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>
194 lines
3.4 KiB
Markdown
194 lines
3.4 KiB
Markdown
---
|
|
name: describe-api
|
|
description: describe/suite for grouping tests into logical blocks
|
|
---
|
|
|
|
# Describe API
|
|
|
|
Group related tests into suites for organization and shared setup.
|
|
|
|
## Basic Usage
|
|
|
|
```ts
|
|
import { describe, expect, test } from 'vitest'
|
|
|
|
describe('Math', () => {
|
|
test('adds numbers', () => {
|
|
expect(1 + 1).toBe(2)
|
|
})
|
|
|
|
test('subtracts numbers', () => {
|
|
expect(3 - 1).toBe(2)
|
|
})
|
|
})
|
|
|
|
// Alias: suite
|
|
import { suite } from 'vitest'
|
|
suite('equivalent to describe', () => {})
|
|
```
|
|
|
|
## Nested Suites
|
|
|
|
```ts
|
|
describe('User', () => {
|
|
describe('when logged in', () => {
|
|
test('shows dashboard', () => {})
|
|
test('can update profile', () => {})
|
|
})
|
|
|
|
describe('when logged out', () => {
|
|
test('shows login page', () => {})
|
|
})
|
|
})
|
|
```
|
|
|
|
## Suite Options
|
|
|
|
```ts
|
|
// All tests inherit options
|
|
describe('slow tests', { timeout: 30_000 }, () => {
|
|
test('test 1', () => {}) // 30s timeout
|
|
test('test 2', () => {}) // 30s timeout
|
|
})
|
|
```
|
|
|
|
## Suite Modifiers
|
|
|
|
### Skip Suites
|
|
|
|
```ts
|
|
describe.skip('skipped suite', () => {
|
|
test('wont run', () => {})
|
|
})
|
|
|
|
// Conditional
|
|
describe.skipIf(process.env.CI)('not in CI', () => {})
|
|
describe.runIf(!process.env.CI)('only local', () => {})
|
|
```
|
|
|
|
### Focus Suites
|
|
|
|
```ts
|
|
describe.only('only this suite runs', () => {
|
|
test('runs', () => {})
|
|
})
|
|
```
|
|
|
|
### Todo Suites
|
|
|
|
```ts
|
|
describe.todo('implement later')
|
|
```
|
|
|
|
### Concurrent Suites
|
|
|
|
```ts
|
|
// All tests run in parallel
|
|
describe.concurrent('parallel tests', () => {
|
|
test('test 1', async ({ expect }) => {})
|
|
test('test 2', async ({ expect }) => {})
|
|
})
|
|
```
|
|
|
|
### Sequential in Concurrent
|
|
|
|
```ts
|
|
describe.concurrent('parallel', () => {
|
|
test('concurrent 1', async () => {})
|
|
|
|
describe.sequential('must be sequential', () => {
|
|
test('step 1', async () => {})
|
|
test('step 2', async () => {})
|
|
})
|
|
})
|
|
```
|
|
|
|
### Shuffle Tests
|
|
|
|
```ts
|
|
describe.shuffle('random order', () => {
|
|
test('test 1', () => {})
|
|
test('test 2', () => {})
|
|
test('test 3', () => {})
|
|
})
|
|
|
|
// Or with option
|
|
describe('random', { shuffle: true }, () => {})
|
|
```
|
|
|
|
## Parameterized Suites
|
|
|
|
### describe.each
|
|
|
|
```ts
|
|
describe.each([
|
|
{ name: 'Chrome', version: 100 },
|
|
{ name: 'Firefox', version: 90 },
|
|
])('$name browser', ({ name, version }) => {
|
|
test('has version', () => {
|
|
expect(version).toBeGreaterThan(0)
|
|
})
|
|
})
|
|
```
|
|
|
|
### describe.for
|
|
|
|
```ts
|
|
describe.for([
|
|
['Chrome', 100],
|
|
['Firefox', 90],
|
|
])('%s browser', ([name, version]) => {
|
|
test('has version', () => {
|
|
expect(version).toBeGreaterThan(0)
|
|
})
|
|
})
|
|
```
|
|
|
|
## Hooks in Suites
|
|
|
|
```ts
|
|
describe('Database', () => {
|
|
let db
|
|
|
|
beforeAll(async () => {
|
|
db = await createDb()
|
|
})
|
|
|
|
afterAll(async () => {
|
|
await db.close()
|
|
})
|
|
|
|
beforeEach(async () => {
|
|
await db.clear()
|
|
})
|
|
|
|
test('insert works', async () => {
|
|
await db.insert({ name: 'test' })
|
|
expect(await db.count()).toBe(1)
|
|
})
|
|
})
|
|
```
|
|
|
|
## Modifier Combinations
|
|
|
|
All modifiers can be chained:
|
|
|
|
```ts
|
|
describe.skip.concurrent('skipped concurrent', () => {})
|
|
describe.only.shuffle('only and shuffled', () => {})
|
|
describe.concurrent.skip('equivalent', () => {})
|
|
```
|
|
|
|
## Key Points
|
|
|
|
- Top-level tests belong to an implicit file suite
|
|
- Nested suites inherit parent's options (timeout, retry, etc.)
|
|
- Hooks are scoped to their suite and nested suites
|
|
- Use `describe.concurrent` with context's `expect` for snapshots
|
|
- Shuffle order depends on `sequence.seed` config
|
|
|
|
<!--
|
|
Source references:
|
|
- https://vitest.dev/api/describe.html
|
|
-->
|