Skip to content
Development
Skill

/cloudflare-workers-testing

Comprehensive testing guide for Cloudflare Workers using Vitest and @cloudflare/vitest-pool-workers. Use for test setup, binding mocks (D1/KV/R2/DO), integration tests, or encountering test failures, mock errors, coverage issues.

From plugin
secondsky-claude-skills
219183 skills42 agents62 commands2 MCP
Install
$ npx -y skills add secondsky/claude-skills --skill cloudflare-workers-testing --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/cloudflare-workers-testing

Context preview

The summary Claude sees to decide when to auto-load this skill.

Comprehensive testing guide for Cloudflare Workers using Vitest and @cloudflare/vitest-pool-workers. Use for test setup, binding mocks (D1/KV/R2/DO), integration tests, or encountering test failures, mock errors, coverage issues.

SKILL.md

cloudflare-workers-testing.SKILL.md
name: cloudflare-workers-testing
description: Comprehensive testing guide for Cloudflare Workers using Vitest and @cloudflare/vitest-pool-workers. Use for test setup, binding mocks (D1/KV/R2/DO), integration tests, or encountering test failures, mock errors, coverage issues.
license: MIT
metadata:
  keywords: "cloudflare-workers, workers-testing, vitest, vitest-workers, miniflare, cloudflare-test, unit-testing, integration-testing, binding-mocks, d1-testing, kv-testing, r2-testing, durable-objects-testing, queue-testing, workers-ai-testing, test-coverage, test-failures, mock-errors, @cloudflare/vitest-pool-workers, cloudflare:test, env-mocking, execution-context, workers-test-setup, vitest-config, test-driven-development, tdd-workers"
  version: "1.0.0"
  last_verified: "2025-01-27"
  production_tested: true
  token_savings: "~70%"
  errors_prevented: 8
  templates_included: 3
  references_included: 5
  scripts_included: 2
  vitest_version: "^2.0.0"
  workers_types_version: "4.20260408.0"
  vitest_pool_workers_version: "0.7.2"

Cloudflare Workers Testing with Vitest

**Status**: ✅ Production Ready | Last Verified: 2025-01-27 **Vitest**: ^2.0.0 | **@cloudflare/vitest-pool-workers**: 0.7.2 | **Miniflare**: Latest

Table of Contents

  • [What Is Workers Testing?](#what-is-workers-testing)
  • [New in 2025](#new-in-2025)
  • [Quick Start (5 Minutes)](#quick-start-5-minutes)
  • [Critical Rules](#critical-rules)
  • [Core Concepts](#core-concepts)
  • [Top 5 Use Cases](#top-5-use-cases)
  • [Best Practices](#best-practices)
  • [Top 8 Errors Prevented](#top-8-errors-prevented)
  • [When to Load References](#when-to-load-references)

---

What Is Workers Testing?

Testing Cloudflare Workers with **Vitest** and **@cloudflare/vitest-pool-workers** enables writing unit and integration tests that run in a real Workers environment with full binding support (D1, KV, R2, Durable Objects, Queues, AI). Tests execute in Miniflare for local development and can run in CI/CD with actual Workers runtime behavior.

**Key capabilities**: Binding mocks, execution context testing, edge runtime simulation, coverage tracking, fast test execution.

---

New in 2025

**@cloudflare/vitest-pool-workers 0.7.2** (January 2025):

  • **BREAKING**: Miniflare v3 → requires Node.js 20+
  • **NEW**: `cloudflare:test` module for env/ctx access
  • **IMPROVED**: Faster isolated storage for bindings
  • **FIXED**: Worker-to-worker service bindings now work correctly
  • **ADDED**: Support for Vectorize and Workers AI bindings

**Migration from older versions**:

# Update dependencies
bun add -D vitest@^2.1.8 @cloudflare/vitest-pool-workers@^0.7.2

# Update vitest.config.ts (new pool configuration format)
export default defineWorkersConfig({
  test: {
    poolOptions: {
      workers: {
        wrangler: { configPath: './wrangler.jsonc' },
        miniflare: { compatibilityDate: '2025-01-27' }
      }
    }
  }
});

---

Quick Start (5 Minutes)

1. Install Dependencies

bun add -D vitest @cloudflare/vitest-pool-workers

2. Create `vitest.config.ts`

import { defineWorkersConfig } from '@cloudflare/vitest-pool-workers/config';

export default defineWorkersConfig({
  test: {
    poolOptions: {
      workers: {
        wrangler: { configPath: './wrangler.jsonc' },
        miniflare: {
          compatibilityDate: '2025-01-27',
          compatibilityFlags: ['nodejs_compat']
        }
      }
    }
  }
});

3. Write Your First Test

import { describe, it, expect } from 'vitest';
import { env, createExecutionContext, waitOnExecutionContext } from 'cloudflare:test';
import worker from '../src/index';

describe('Worker', () => {
  it('responds with 200', async () => {
    const request = new Request('http://example.com/');
    const ctx = createExecutionContext();
    const response = await worker.fetch(request, env, ctx);
    await waitOnExecutionContext(ctx);

    expect(response.status).toBe(200);
  });
});

4. Run Tests

bun test
# or
bunx vitest

---

Critical Rules

1. Always Use `cloudflare:test` for Env Access

**✅ CORRECT**:

import { env } from 'cloudflare:test';

it('queries D1', async () => {
  const result = await env.DB.prepare('SELECT * FROM users').all();
  expect(result.results).toHaveLength(0); // Fresh isolated DB per test
});

**❌ WRONG**:

// Don't manually create env object
const env = { DB: mockDB }; // ❌ Won't use real D1 binding

**Why**: `cloudflare:test` provides real bindings configured from `wrangler.jsonc` with isolated storage per test.

2. Always Wait on Execution Context

**✅ CORRECT**:

it('handles async operations', async () => {
  const ctx = createExecutionContext();
  const response = await worker.fetch(request, env, ctx);
  await waitOnExecutionContext(ctx); // ✅ Ensures ctx.waitUntil completes

  expect(response.status).toBe(200);
});

**❌ WRONG**:

it('missing wait', async () => {
  const ctx = createExecutionContext();
  const response = await worker.fetch(request, env, ctx);
  // ❌ Missing waitOnExecutionContext - ctx.waitUntil tasks may not complete
  expect(response.status).toBe(200);
});

**Why**: Workers use `ctx.waitUntil()` for background tasks (logging, analytics). Without waiting, these tasks may not complete in tests.

3. Each Test Gets Isolated Storage

**✅ CORRECT**:

describe('KV Operations', () => {
  it('test 1: writes to KV', async () => {
    await env.CACHE.put('key', 'value1');
    const val = await env.CACHE.get('key');
    expect(val).toBe('value1'); // ✅ Isolated
  });

  it('test 2: clean state', async () => {
    const val = await env.CACHE.get('key');
    expect(val).toBeNull(); // ✅ Test 1's data doesn't leak here
  });
});

**Why**: Each test runs with fresh binding storage (automatic isolation).

4. Use Wrangler Config for Bindings

**✅ CORRECT**:

// vitest.config.ts
exp
Read more
Ships withsecondsky-claude-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).

Get the whole plugin

Other skills on secondsky-claude-skills.