All skills

Use when writing unit/integration tests for Vite projects - provides Vitest configuration, test APIs, mocking patterns, and coverage setup

  • 6 files
  • 24.3 KB
  • MIT
  • Updated 8 months ago
  • GitHub

Use this Skill: https://skilld.dev/gh/onmax/claude-config/vitest

This session only. Nothing lands on disk.

referencestest-api.md

≈1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Test API

Basic Tests

import { describe, expect, it, test } from 'vitest'

test('adds numbers', () => {
  expect(1 + 1).toBe(2)
})

// Alias: it
it('works the same', () => {
  expect(true).toBe(true)
})

Async Tests

test('async test', async () => {
  const result = await fetchData()
  expect(result).toBeDefined()
})

Test Options

test('with options', { timeout: 10_000, retry: 2 }, async () => {})
test('with tags', { tags: ['db', 'slow'] }, async () => {})

Modifiers

test.skip('skipped', () => {})
test.only('only this runs', () => {})
test.todo('implement later')
test.fails('expected to fail', () => { expect(1).toBe(2) })
test.skipIf(process.env.CI)('not in CI', () => {})
test.runIf(process.env.CI)('only in CI', () => {})

// Dynamic skip
test('dynamic', ({ skip }) => {
  skip(someCondition, 'reason')
})

Concurrent & Sequential

test.concurrent('parallel 1', async ({ expect }) => {})
test.concurrent('parallel 2', async ({ expect }) => {})
test.sequential('must run alone', async () => {})

Important: Use { expect } from context for concurrent tests.

Parameterized Tests

test.each([
  [1, 1, 2],
  [1, 2, 3],
])('add(%i, %i) = %i', (a, b, expected) => {
  expect(a + b).toBe(expected)
})

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)
})

// test.for - preferred, doesn't spread arrays
test.for([
  [1, 1, 2],
  [1, 2, 3],
])('add(%i, %i) = %i', ([a, b, expected], { expect }) => {
  expect(a + b).toBe(expected)
})

Describe/Suite

describe('Math', () => {
  test('adds', () => expect(1 + 1).toBe(2))
  test('subtracts', () => expect(3 - 1).toBe(2))
})

// Nested
describe('User', () => {
  describe('when logged in', () => {
    test('shows dashboard', () => {})
  })
})

// Modifiers
describe.skip('skipped', () => {})
describe.only('only this', () => {})
describe.concurrent('parallel', () => {})
describe.shuffle('random order', () => {})
describe.each([{ name: 'Chrome' }, { name: 'Firefox' }])('$name', ({ name }) => {})

Lifecycle Hooks

import { afterAll, afterEach, beforeAll, beforeEach } from 'vitest'

beforeAll(async () => { await setupDatabase() })
afterAll(async () => { await teardownDatabase() })
beforeEach(async () => { await clearTestData() })
afterEach(async () => { await cleanupMocks() })

// Return cleanup function
beforeAll(async () => {
  const server = await startServer()
  return async () => { await server.close() }
})

Around Hooks

import { aroundEach, aroundAll } from 'vitest'

aroundEach(async (runTest) => {
  await db.beginTransaction()
  await runTest()  // Must be called!
  await db.rollback()
})

Test Hooks

import { onTestFailed, onTestFinished } from 'vitest'

test('with cleanup', () => {
  const db = connect()
  onTestFinished(() => db.close())
  onTestFailed(({ task }) => { console.log('Failed:', task.result?.errors) })
})

// Reusable pattern
function useTestDb() {
  const db = connect()
  onTestFinished(() => db.close())
  return db
}

Custom Fixtures

import { test as base } from 'vitest'

const test = base.extend<{ db: Database; user: User }>({
  db: async ({}, use) => {
    const db = await createDb()
    await use(db)
    await db.close()
  },
  user: async ({ db }, use) => {
    const user = await db.createUser({ name: 'Test' })
    await use(user)
    await db.deleteUser(user.id)
  },
})

test('query', async ({ db, user }) => {
  const found = await db.findUser(user.id)
  expect(found).toEqual(user)
})

// Fixture options
const test = base.extend({
  setup: [async ({}, use) => { await use() }, { auto: true }],  // Always run
  connection: [async ({}, use) => { /* ... */ }, { scope: 'file' }],  // Once per file
})

Hook Execution Order

  1. beforeAll (in order)
  2. beforeEach (in order)
  3. Test
  4. afterEach (reverse order)
  5. afterAll (reverse order)

Configure with sequence.hooks: 'stack' | 'list' | 'parallel'

Source: SKILL.md on GitHub

No third-party reports yet.

Signed by skilld at 6a37106. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 8 hours ago.

Activeupdated 8 months ago

README badge

README badge for onmax/claude-config/vitest