設定済みルート経由でリクエストを送るか、特定の Worker を直接対象にするには、テストハーネスを使います。scheduled イベントなどのイベントもディスパッチできます。
テストハーネスが複数の Worker を動かす場合は、各 Worker を workers 配列に追加します。先頭の Worker がプライマリ Worker です。server.fetch() は相対 URL をプライマリ Worker に送り、絶対 URL は設定済みルートと照合します。ルートに一致しない場合は、プライマリ Worker にフォールバックします。
const server = createTestHarness({
workers: [
/** Includes `"routes": ["example.com/*"]` */
{ configPath: "./workers/web/wrangler.jsonc" },
/** Includes `"routes": ["api.example.com/v1/*"]` */
{ configPath: "./workers/api/wrangler.jsonc" },
],
});
const primaryResponse = await server.fetch("/");
const apiResponse = await server.fetch("http://api.example.com/v1/users/123");
const webResponse = await server.fetch("http://example.com/users/123");const server = createTestHarness({
workers: [
/** Includes `"routes": ["example.com/*"]` */
{ configPath: "./workers/web/wrangler.jsonc" },
/** Includes `"routes": ["api.example.com/v1/*"]` */
{ configPath: "./workers/api/wrangler.jsonc" },
],
});
const primaryResponse = await server.fetch("/");
const apiResponse = await server.fetch("http://api.example.com/v1/users/123");
const webResponse = await server.fetch("http://example.com/users/123");ルートディスパッチはアプリケーション境界をテストします。一方、1 つの Worker を対象にしたり、ほかのイベントハンドラーを起動したりしたいテストもあります。ルート照合をバイパスしてその Worker のハンドルを取得するには、server.getWorker(name) を使います。
この Worker ハンドルで、リクエストを直接送ったり、scheduled() などのほかのイベントをディスパッチしたりできます。
const apiWorker = server.getWorker("api-worker");
const response = await apiWorker.fetch("http://api.example.com/v1/users/123");
await apiWorker.scheduled({
cron: "0 0 * * *",
scheduledTime: new Date(),
});const apiWorker = server.getWorker("api-worker");
const response = await apiWorker.fetch("http://api.example.com/v1/users/123");
await apiWorker.scheduled({
cron: "0 0 * * *",
scheduledTime: new Date(),
});テストハーネスは、Workers ランタイムのログをキャプチャします。Worker が特定のメッセージを記録したことを検証するには、server.getLogs() でログエントリを取得します。
キャプチャしたログは、server.reset() を呼ぶとリセットされます。特定の操作の前後でログを切り分けるには、server.clearLogs() も使えます。
test("logs scheduled job results", async ({ expect }) => {
const apiWorker = server.getWorker("api-worker");
await apiWorker.scheduled({
cron: "0 0 * * *",
scheduledTime: new Date("2026-05-29T00:00:00.000Z"),
});
expect(server.getLogs()).toEqual([
expect.objectContaining({
level: "info",
message: "Generated daily report for 2026-05-29",
}),
]);
server.clearLogs();
await apiWorker.scheduled({
cron: "0 0 * * *",
scheduledTime: new Date("2026-05-30T00:00:00.000Z"),
});
expect(server.getLogs()).toEqual([
expect.objectContaining({
level: "info",
message: "Generated daily report for 2026-05-30",
}),
]);
});test("logs scheduled job results", async ({ expect }) => {
const apiWorker = server.getWorker("api-worker");
await apiWorker.scheduled({
cron: "0 0 * * *",
scheduledTime: new Date("2026-05-29T00:00:00.000Z"),
});
expect(server.getLogs()).toEqual([
expect.objectContaining({
level: "info",
message: "Generated daily report for 2026-05-29",
}),
]);
server.clearLogs();
await apiWorker.scheduled({
cron: "0 0 * * *",
scheduledTime: new Date("2026-05-30T00:00:00.000Z"),
});
expect(server.getLogs()).toEqual([
expect.objectContaining({
level: "info",
message: "Generated daily report for 2026-05-30",
}),
]);
});Worker が Workflow を開始する場合は、worker.introspectWorkflow(bindingName) で新しいインスタンスを制御し、状態を検査できます。
const worker = server.getWorker("api-worker");
await using workflow = await worker.introspectWorkflow("MY_WORKFLOW");
await workflow.modifyAll(async (modifier) => {
await modifier.disableSleeps([{ name: "wait-for-approval" }]);
});
await worker.fetch("/start-workflow");
const [instance] = await workflow.get();
await instance.waitForStatus("complete");
expect(await instance.getOutput()).toEqual({ approved: true });const worker = server.getWorker<ApiEnv>("api-worker");
await using workflow = await worker.introspectWorkflow("MY_WORKFLOW");
await workflow.modifyAll(async (modifier) => {
await modifier.disableSleeps([{ name: "wait-for-approval" }]);
});
await worker.fetch("/start-workflow");
const [instance] = await workflow.get();
await instance.waitForStatus("complete");
expect(await instance.getOutput()).toEqual({ approved: true });テストがインスタンス ID をすでに知っている場合は、worker.introspectWorkflowInstance(bindingName, instanceId) でそのインスタンスを直接検査することもできます。
const instance = await worker.introspectWorkflowInstance(
"MY_WORKFLOW",
"instance-id",
);
await instance.modify(async (modifier) => {
await modifier.mockStepResult({ name: "load-user" }, { id: "123" });
});
await instance.waitForStatus("complete");const instance = await worker.introspectWorkflowInstance(
"MY_WORKFLOW",
"instance-id",
);
await instance.modify(async (modifier) => {
await modifier.mockStepResult({ name: "load-user" }, { id: "123" });
});
await instance.waitForStatus("complete");