Detailed guide for authoring .wd-test files in workerd, with examples of bindings, Durable Objects, multi-service configs, TypeScript tests, and network access.
npx skills add https://github.com/cloudflare/workerd --skill wd-test-format
.wd-test File Format.wd-test files are Cap'n Proto configs that define test workers for workerd's test framework. They use the schema defined in src/workerd/server/workerd.capnp.
This skill is split across multiple files for context efficiency. The core patterns below cover
standard single-service tests. Advanced configuration patterns live in a reference file.
**You MUST read the reference file before writing or reviewing test configs that involve its
subject matter. Do not guess at advanced config syntax — the reference file contains the exact
patterns and fields required. Skipping it WILL lead to incorrect configs that fail at runtime.**
| File | MUST load when... |
| ------------------------------- | ------------------------------------------------------------ |
| reference/advanced-configs.md | Test involves Durable Objects, multiple services |
| | communicating via service bindings, outbound network access, |
| | external services/sockets, or TypeScript source files |
When in doubt about whether the reference file is relevant, load it — the cost of reading is
far less than the cost of a broken test config.
using Workerd = import "/workerd/workerd.capnp";
const unitTests :Workerd.Config = (
services = [(
name = "my-test",
worker = (
modules = [(name = "worker", esModule = embed "my-test.js")],
compatibilityFlags = ["nodejs_compat_v2"],
),
)],
);
Key rules:
unitTests) must match what the test runner expectsmodules uses embed to inline file contents at build time"worker" — this is the entry pointcompatibilityFlags control which APIs are available. Use the compat-date-at tool to look up available flags and their enable dates.compatibilityDate should not be used in wd-test; use specific flags insteadmodules = [
(name = "worker", esModule = embed "my-test.js"), # ES module (most common)
(name = "helper", esModule = embed "helper.js"), # Additional ES module
(name = "data.json", json = embed "test-data.json"), # JSON module
(name = "data.wasm", wasm = embed "module.wasm"), # WebAssembly module
(name = "legacy", commonJsModule = embed "legacy.js"), # CommonJS module
],
Bindings make services, data, and namespaces available to the worker via env:
bindings = [
# Text binding — env.MY_TEXT is a string
(name = "MY_TEXT", text = "hello world"),
# Text from file
(name = "CERT", text = embed "fixtures/cert.pem"),
# Data binding — env.MY_DATA is an ArrayBuffer
(name = "MY_DATA", data = "base64encodeddata"),
# JSON binding — env.CONFIG is a parsed object
(name = "CONFIG", json = "{ \"key\": \"value\" }"),
# Service binding — env.OTHER_SERVICE is a fetch-able service
(name = "OTHER_SERVICE", service = "other-service-name"),
# Service binding with entrypoint
(name = "MY_RPC", service = (name = "my-service", entrypoint = "MyClass")),
# KV namespace — env.KV is a KV namespace
(name = "KV", kvNamespace = "kv-namespace-id"),
# Durable Object namespace — env.MY_DO is a DO namespace
(name = "MY_DO", durableObjectNamespace = "MyDurableObject"),
],
Test files export named objects with a test() method:
// Each export becomes a separate test case
export const basicTest = {
test() {
// Synchronous test
assert.strictEqual(1 + 1, 2);
},
};
export const asyncTest = {
async test(ctrl, env) {
// ctrl is the test controller
// env contains bindings from the .wd-test config
const resp = await env.OTHER_SERVICE.fetch('http://example.com/');
assert.strictEqual(resp.status, 200);
},
};
wd_test(
src = "my-test.wd-test",
args = ["--experimental"], # Required for experimental features
data = ["my-test.js"], # Test JS/TS files
)
Additional data entries for fixture files:
wd_test(
src = "crypto-test.wd-test",
args = ["--experimental"],
data = [
"crypto-test.js",
"fixtures/cert.pem",
"fixtures/key.pem",
],
)
Every wd_test() automatically generates three variants:
| Target suffix | Compat date | Description |
| ------------------- | ----------- | -------------------------------------- |
| @ | 2000-01-01 | Default, tests with oldest compat date |
| @all-compat-flags | 2999-12-31 | Tests with all flags enabled |
| @all-autogates | 2000-01-01 | Tests with all autogates enabled |
Run specific variants:
just stream-test //src/workerd/api/tests:my-test@
just stream-test //src/workerd/api/tests:my-test@all-compat-flags
Use just new-test to scaffold a new test:
just new-test //src/workerd/api/tests:my-test
This creates the .wd-test file, .js test file, and appends the wd_test() rule to BUILD.bazel.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Comprehensive GitHub release orchestration with AI swarm coordination for automated versioning, testing, deployment, and rollback management
Migrate test files from `as` type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace `as` in tests, or needs partial test data.
Modern JavaScript/TypeScript development with Bun runtime. Covers package management, bundling, testing, and migration from Node.js. Use when working with Bun, optimizing JS/TS development speed, or migrating from Node.js to Bun.
You are a dependency management expert specializing in safe, incremental upgrades of project dependencies. Plan and execute dependency updates with minimal risk, proper testing, and clear migration pa
Master systematic debugging techniques, profiling tools, and root cause analysis to efficiently track down bugs across any codebase or technology stack. Use when investigating bugs, performance issues, or unexpected behavior.
Opinionated backend development standards for Node.js + Express + TypeScript microservices. Covers layered architecture, BaseController pattern, dependency injection, Prisma repositories, Zod validation, unifiedConfig, Sentry error tracking, async safety, and testing discipline.
Best practices for writing JavaScript/TypeScript tests using Jest, including mocking strategies, test structure, and common patterns.
Take cloudflare/wd-test-format from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.