Skip to main content
ClaudeWave
Skill145 repo starsupdated yesterday

Bun Test Runner

Fast test execution with Bun's built-in test runner including snapshot testing, mocking, code coverage, lifecycle hooks, DOM testing with happy-dom, and migration from Jest and Vitest to Bun test.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/PramodDutta/qaskills /tmp/bun-test-runner && cp -r /tmp/bun-test-runner/seed-skills/bun-testing ~/.claude/skills/bun-test-runner
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Bun Test Runner Skill

You are an expert in Bun's built-in test runner. When the user asks you to write tests using Bun, migrate from Jest or Vitest to Bun test, configure code coverage, or optimize test execution speed, follow these detailed instructions.

## Core Principles

1. **Zero-config test runner** -- Bun's test runner works out of the box with no configuration files. Tests are discovered automatically by filename patterns.
2. **Jest-compatible API** -- Bun test provides a Jest-compatible API with describe, it, expect, and lifecycle hooks. Migration from Jest is straightforward.
3. **Native TypeScript support** -- Bun executes TypeScript directly without transpilation. No ts-jest or tsconfig paths configuration needed.
4. **Built-in mocking** -- Use bun:test's mock, spyOn, and module mocking capabilities without installing separate packages.
5. **Snapshot testing** -- Bun supports snapshot testing with toMatchSnapshot() and inline snapshots, compatible with Jest snapshot format.
6. **Code coverage** -- Generate code coverage reports with --coverage flag. No additional tools like c8 or istanbul needed.
7. **Parallel by default** -- Bun runs test files in parallel by default. Design tests to be independent for correct parallel execution.

## Project Structure

```
src/
  utils/
    math.ts
    math.test.ts
    string.ts
    string.test.ts
  services/
    user-service.ts
    user-service.test.ts
    api-client.ts
    api-client.test.ts
  db/
    queries.ts
    queries.test.ts
  __snapshots__/
    .gitkeep
bunfig.toml
package.json
```

## Bun Configuration

```toml
# bunfig.toml
[test]
# Test file patterns
root = "./src"

# Coverage configuration
coverage = true
coverageReporter = ["text", "lcov"]
coverageThreshold = { line = 80, function = 80, statement = 80 }

# Preload scripts
preload = ["./test-setup.ts"]

# Timeout per test (ms)
timeout = 5000

# Bail after N failures (0 = no bail)
bail = 0
```

## Basic Test Patterns

```typescript
// src/utils/math.test.ts
import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
import { add, multiply, divide, fibonacci, isPrime } from './math';

describe('Math Utilities', () => {
  describe('add', () => {
    it('should add two positive numbers', () => {
      expect(add(2, 3)).toBe(5);
    });

    it('should handle negative numbers', () => {
      expect(add(-1, -2)).toBe(-3);
      expect(add(-1, 5)).toBe(4);
    });

    it('should handle zero', () => {
      expect(add(0, 0)).toBe(0);
      expect(add(5, 0)).toBe(5);
    });

    it('should handle floating point', () => {
      expect(add(0.1, 0.2)).toBeCloseTo(0.3);
    });
  });

  describe('divide', () => {
    it('should divide two numbers', () => {
      expect(divide(10, 2)).toBe(5);
    });

    it('should throw on division by zero', () => {
      expect(() => divide(10, 0)).toThrow('Division by zero');
    });

    it('should handle decimal results', () => {
      expect(divide(1, 3)).toBeCloseTo(0.333, 2);
    });
  });

  describe('fibonacci', () => {
    it('should return correct values for small inputs', () => {
      expect(fibonacci(0)).toBe(0);
      expect(fibonacci(1)).toBe(1);
      expect(fibonacci(2)).toBe(1);
      expect(fibonacci(10)).toBe(55);
    });

    it('should throw for negative inputs', () => {
      expect(() => fibonacci(-1)).toThrow();
    });
  });

  describe('isPrime', () => {
    it.each([2, 3, 5, 7, 11, 13])('should identify %d as prime', (n) => {
      expect(isPrime(n)).toBe(true);
    });

    it.each([0, 1, 4, 6, 8, 9, 10])('should identify %d as not prime', (n) => {
      expect(isPrime(n)).toBe(false);
    });
  });
});
```

## Mocking with Bun

```typescript
// src/services/user-service.test.ts
import { describe, it, expect, mock, spyOn, beforeEach } from 'bun:test';
import { UserService } from './user-service';
import { db } from '../db/connection';

// Mock the entire module
mock.module('../db/connection', () => ({
  db: {
    query: mock(() => Promise.resolve([])),
    insert: mock(() => Promise.resolve({ id: '123' })),
    update: mock(() => Promise.resolve({ affected: 1 })),
    delete: mock(() => Promise.resolve({ affected: 1 })),
  },
}));

describe('UserService', () => {
  let service: UserService;

  beforeEach(() => {
    service = new UserService();
    // Reset all mocks
    (db.query as any).mockClear();
    (db.insert as any).mockClear();
  });

  it('should find a user by ID', async () => {
    const mockUser = { id: '123', name: 'Alice', email: 'alice@test.com' };
    (db.query as any).mockResolvedValueOnce([mockUser]);

    const user = await service.findById('123');

    expect(user).toEqual(mockUser);
    expect(db.query).toHaveBeenCalledTimes(1);
  });

  it('should return null for non-existent user', async () => {
    (db.query as any).mockResolvedValueOnce([]);

    const user = await service.findById('nonexistent');

    expect(user).toBeNull();
  });

  it('should create a new user', async () => {
    const newUser = { name: 'Bob', email: 'bob@test.com' };
    (db.insert as any).mockResolvedValueOnce({ id: '456', ...newUser });

    const created = await service.create(newUser);

    expect(created.id).toBe('456');
    expect(db.insert).toHaveBeenCalledTimes(1);
  });

  it('should throw on duplicate email', async () => {
    (db.insert as any).mockRejectedValueOnce(new Error('UNIQUE constraint failed'));

    expect(service.create({ name: 'Bob', email: 'existing@test.com' })).rejects.toThrow(
      'Email already exists'
    );
  });
});
```

## Spy Functions

```typescript
// src/services/api-client.test.ts
import { describe, it, expect, spyOn, mock, beforeEach, afterEach } from 'bun:test';
import { ApiClient } from './api-client';

describe('ApiClient', () => {
  let client: ApiClient;
  let fetchSpy: any;

  beforeEach(() => {
    client = new ApiClient('https://api.example.com');
    fetchSpy = spyOn(globalThis, 'fetch');
  });

  afterEach(() => {
    fetchSpy.mockRestore();
  });

  it('shoul
axe-core Accessibility AutomationSkill

Automated accessibility testing with axe-core integrated into CI pipelines, including custom rule configuration, issue prioritization, and remediation guidance.

A/B Test ValidationSkill

Validating A/B test implementations including traffic splitting accuracy, statistical significance calculation, metric tracking, and experiment cleanup.

Accessibility A11y EnhancedSkill

Comprehensive WCAG compliance and accessibility testing covering ARIA, keyboard navigation, screen readers, color contrast, and automated a11y validation.

Accessibility AuditorSkill

Comprehensive WCAG 2.1 AA compliance testing combining automated axe-core scans with manual keyboard navigation, screen reader compatibility, and focus management verification

AFL++ Fuzzing TestingSkill

American Fuzzy Lop Plus Plus mutation-based fuzz testing for finding crashes, hangs, and security vulnerabilities in binary programs.

Agent Browser AutomationSkill

Fast Rust-based headless browser automation CLI with Node.js fallback for AI agents, featuring navigation, clicking, typing, snapshots, and structured commands optimized for agent workflows.

Agentic Testing PatternsSkill

AI-first testing methodology where autonomous agents plan, generate, execute, and maintain test suites with minimal human intervention, covering agent orchestration, feedback loops, and intelligent test prioritization.

AI Agent EvaluationSkill

Comprehensive evaluation patterns for AI agents including multi-turn conversation testing, LLM-as-judge frameworks, benchmark suites, regression detection, and systematic eval pipelines for measuring agent quality and safety.