Skip to content
Development
Skill

/vitest-testing

Modern TypeScript/JavaScript testing with Vitest. Fast unit and integration tests, native ESM support, Vite-powered HMR, and comprehensive mocking. Use for testing TS/JS projects.

From plugin
claude-skills
241183 skills42 agents62 commands2 MCP

Claude Code

$ npx -y skills add secondsky/claude-skills --skill vitest-testing --agent claude-code

SKILL.md

vitest-testing.SKILL.md
name: vitest-testing
description: Modern TypeScript/JavaScript testing with Vitest. Fast unit and integration tests, native ESM support, Vite-powered HMR, and comprehensive mocking. Use for testing TS/JS projects.
allowed-tools: Bash, Read, Edit, Write, Grep, Glob, TodoWrite
license: MIT

Vitest Testing

Expert knowledge for testing JavaScript/TypeScript projects using Vitest - a blazingly fast testing framework powered by Vite.

Quick Start

Installation

# Using Bun (recommended)
bun add -d vitest

# Using npm
npm install -D vitest

Configuration

// vitest.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    globals: true,
    environment: 'node', // or 'jsdom'
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      thresholds: { lines: 80, functions: 80, branches: 80 },
    },
    include: ['**/*.{test,spec}.{js,ts,jsx,tsx}'],
  },
})

Running Tests

# Run all tests (prefer bun)
bun test

# Watch mode (default)
bun test --watch

# Run once (CI mode)
bun test --run

# With coverage
bun test --coverage

# Specific file
bun test src/utils/math.test.ts

# Pattern matching
bun test --grep="calculates sum"

# UI mode (interactive)
bun test --ui

# Verbose output (in Vitest 2+, --reporter=verbose prints a flat list;
# use --reporter=tree for the hierarchical tree view)
bun test --reporter=verbose

Writing Tests

Basic Structure

import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { add, subtract } from './math'

describe('Math utilities', () => {
  beforeEach(() => {
    // Setup before each test
  })

  it('adds two numbers correctly', () => {
    expect(add(2, 3)).toBe(5)
  })

  it('subtracts two numbers correctly', () => {
    expect(subtract(5, 3)).toBe(2)
  })
})

Parametrized Tests

describe.each([
  { input: 2, expected: 4 },
  { input: 3, expected: 9 },
])('square function', ({ input, expected }) => {
  it(`squares ${input} to ${expected}`, () => {
    expect(square(input)).toBe(expected)
  })
})

Assertions

// Equality
expect(value).toBe(expected)
expect(value).toEqual(expected)

// Truthiness
expect(value).toBeTruthy()
expect(value).toBeNull()
expect(value).toBeDefined()

// Numbers
expect(number).toBeGreaterThan(3)
expect(number).toBeCloseTo(0.3, 1)

// Strings/Arrays
expect(string).toMatch(/pattern/)
expect(array).toContain(item)

// Objects
expect(object).toHaveProperty('key')
expect(object).toMatchObject({ a: 1 })

// Exceptions
expect(() => throwError()).toThrow('message')

// Promises
await expect(promise).resolves.toBe(value)
await expect(promise).rejects.toThrow()

Mocking

Function Mocks

import { vi } from 'vitest'

const mockFn = vi.fn()
mockFn.mockReturnValue(42)
mockFn.mockResolvedValue('async result')
mockFn.mockImplementation((x) => x * 2)

expect(mockFn).toHaveBeenCalled()
expect(mockFn).toHaveBeenCalledWith('arg')

Module Mocking

vi.mock('./api', () => ({
  fetchUser: vi.fn(() => ({ id: 1, name: 'Test User' })),
}))

import { fetchUser } from './api'

beforeEach(() => {
  vi.clearAllMocks()
})

Timers

beforeEach(() => vi.useFakeTimers())
afterEach(() => vi.restoreAllMocks())

it('advances timers', () => {
  const callback = vi.fn()
  setTimeout(callback, 1000)
  vi.advanceTimersByTime(1000)
  expect(callback).toHaveBeenCalledOnce()
})

it('mocks dates', () => {
  const date = new Date('2024-01-01')
  vi.setSystemTime(date)
  expect(Date.now()).toBe(date.getTime())
})

Coverage

# Generate coverage report
bun test --coverage

# HTML report
bun test --coverage --coverage.reporter=html
open coverage/index.html

# Check against thresholds
bun test --coverage --coverage.thresholds.lines=90

Integration Testing

import request from 'supertest'
import { app } from './app'

describe('API endpoints', () => {
  it('creates a user', async () => {
    const response = await request(app)
      .post('/api/users')
      .send({ name: 'John' })
      .expect(201)

    expect(response.body).toMatchObject({
      id: expect.any(Number),
      name: 'John',
    })
  })
})

Best Practices

  • One test file per source file: `math.ts` → `math.test.ts`
  • Group related tests with `describe()` blocks
  • Use descriptive test names
  • Mock only external dependencies
  • Use `concurrent` tests for independent async tests
  • Share expensive fixtures with `beforeAll()`
  • Aim for 80%+ coverage but don't chase 100%

See Also

  • `test-quality-analysis` - Detecting test smells
  • `playwright-testing` - E2E testing
  • `mutation-testing` - Validate test effectiveness
Read more
@secondsky
Ships withclaude-skills

145 production-ready skills for Claude Code CLI 🔌 Platform / Harness Support These plugins ship as Claude Code marketplace plugins (.claude-plugin/ manifests) and Codex CLI plugins (.codex-plugin/ manifests).

241183 skills42 agents2 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
241
Star history of secondsky/claude-skills on GitHub, a chart by star-history.com

Other skills on claude-skills.

aceternity-ui

aceternity-ui

100+ animated React components (Aceternity UI) for Next.js with Tailwind. Use for hero sections, parallax, 3D effects, or…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about vitest-testing.

Which coding agents can use vitest-testing?
vitest-testing installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.