使用测试 harness 通过已配置的路由发送请求,或直接定向到特定 Worker。你也可以派发 scheduled 等事件。
当测试 harness 运行多个 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");路由派发测试应用边界,但有些测试可能想定向到一个 Worker 或触发其他事件处理程序。使用 server.getWorker(name) 绕过路由匹配,并获取该 Worker 的 handle。
然后可以使用此 Worker handle 直接发送请求,或派发其他事件,例如 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(),
});测试 harness 会捕获来自 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");