wd-test-format
$
npx mdskill add cloudflare/workerd/wd-test-formatGenerate correct `.wd-test` configurations for testing complex workerd services and components.
- Author test worker definitions covering bindings, Durable Objects, and multi-service setups.
- Integrates with the workerd test framework and Cap'n Proto schema definitions.
- Requires loading advanced configuration patterns for complex testing scenarios.
- Provides detailed, structured guides and examples for writing functional test files.
SKILL.md
.github/skills/wd-test-formatView on GitHub ↗
---
name: wd-test-format
description: Detailed guide for authoring .wd-test files in workerd, with examples of bindings, Durable Objects, multi-service configs, TypeScript tests, and network access.
---
## `.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`.
---
### MANDATORY: Load Reference File When Relevant
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.
---
### Basic Structure
```capnp
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:
- The const name (e.g., `unitTests`) must match what the test runner expects
- `modules` uses `embed` to inline file contents at build time
- The first module should be named `"worker"` — this is the entry point
- `compatibilityFlags` 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 instead
### Module Types
```capnp
modules = [
(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
Bindings make services, data, and namespaces available to the worker via `env`:
```capnp
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 JavaScript Structure
Test files export named objects with a `test()` method:
```javascript
// 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);
},
};
```
### BUILD.bazel Integration
```python
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:
```python
wd_test(
src = "crypto-test.wd-test",
args = ["--experimental"],
data = [
"crypto-test.js",
"fixtures/cert.pem",
"fixtures/key.pem",
],
)
```
### Test Variants
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:
```bash
just stream-test //src/workerd/api/tests:my-test@
just stream-test //src/workerd/api/tests:my-test@all-compat-flags
```
### Scaffolding
Use `just new-test` to scaffold a new test:
```bash
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`.
More from cloudflare/workerd
- add-autogateStep-by-step guide for adding a new autogate to workerd for gradual rollout of risky changes, including enum registration, string mapping, usage pattern, and testing.
- add-compat-flagStep-by-step guide for adding a new compatibility flag to workerd, including capnp schema, C++ usage, testing, and documentation requirements.
- bazel-test-hygieneMandatory rules for running bazel tests during development. Load this skill before running any bazel test command, especially when validating fixes or verifying regression tests. Prevents false confidence from cached results, filter flags that silently match nothing, and partial test runs that miss breakage.
- commit-categoriesCommit categorization rules for changelogs and "what's new" summaries. MUST be loaded before categorizing commits in changelog or whats-new commands. Provides the canonical path-based category table used to group commits by area.
- dad-jokesAfter completing any task that took more than ~5 tool calls, or after long-running builds/tests finish, load this skill and deliver a dad joke to lighten the mood. Also load before any user-requested joke, pun, or limerick. Never improvise jokes without loading this skill first.
- find-and-run-testsHow to find, build, and run tests in workerd. Covers wd-test, kj_test target naming, bazel query patterns, and common flags. Also covers parent project integration tests if workerd is used as a submodule. Load this skill when you need to locate or run a test and aren't sure of the exact target name or invocation.
- identify-reviewerIdentifies the local user's GitHub account and git identity before performing code reviews. Load this skill at the start of any PR review, code review, or commit log analysis so findings can be framed relative to the user's own prior comments, commits, and approval status.
- investigation-notesStructured scratch tracking document for investigation state during bug hunts - prevents re-reading code, losing context, and rabbit holes; maintains external memory so you don't re-derive conclusions
- kj-styleKJ/workerd C++ style guidelines for code review. Covers naming, type usage, memory management, error handling, inheritance, constness, and formatting conventions. Load this skill when reviewing or writing C++ code in the workerd codebase.
- markdown-draftsUse markdown formatting when drafting content intended for external systems (GitHub issues/PRs, Jira tickets, wiki pages, design docs, etc.) so formatting is preserved when the user copies it. Load this skill before producing any draft the user will paste elsewhere.