您可以将 createTestHarness() 与 Node.js 生态系统中的现有工具配合使用。本页面的示例展示了可根据您的测试设置调整的常见集成模式。
如果 Worker 发起出站 fetch() 请求,您可以使用 Mock Service Worker (MSW) ↗ 拦截并返回可预测的响应。MSW 提供可在测试之间共享的可复用请求处理程序。
例如,您可以在测试前启动 MSW、拒绝未处理的请求,并在每次测试后重置处理程序:
import { afterAll, afterEach, beforeAll, test } from "vitest";
import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";
import { createTestHarness } from "wrangler";
const network = setupServer();
const server = createTestHarness({
workers: [{ configPath: "./wrangler.jsonc" }],
});
beforeAll(async () => {
network.listen({ onUnhandledRequest: "error" });
await server.listen();
});
afterEach(async () => {
network.resetHandlers();
await server.reset();
});
afterAll(async () => {
network.close();
await server.close();
});
test("loads a user profile", async ({ expect }) => {
network.use(
http.get("http://identity.example.com/profile/:id", ({ params }) => {
return HttpResponse.json({ id: params.id, name: "Ada" });
}),
);
const worker = server.getWorker();
const response = await worker.fetch("/users/123");
expect(await response.json()).toEqual({ id: "123", name: "Ada" });
});import { afterAll, afterEach, beforeAll, test } from "vitest";
import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";
import { createTestHarness } from "wrangler";
const network = setupServer();
const server = createTestHarness({
workers: [{ configPath: "./wrangler.jsonc" }],
});
beforeAll(async () => {
network.listen({ onUnhandledRequest: "error" });
await server.listen();
});
afterEach(async () => {
network.resetHandlers();
await server.reset();
});
afterAll(async () => {
network.close();
await server.close();
});
test("loads a user profile", async ({ expect }) => {
network.use(
http.get("http://identity.example.com/profile/:id", ({ params }) => {
return HttpResponse.json({ id: params.id, name: "Ada" });
}),
);
const worker = server.getWorker();
const response = await worker.fetch("/users/123");
expect(await response.json()).toEqual({ id: "123", name: "Ada" });
});如果您正在构建 Web 应用程序,并希望在真实浏览器中验证用户流程,请将 Playwright ↗ 与测试框架配合使用。Playwright 可以导航页面、与用户界面交互,并端到端验证 Workers 项目的行为。
Playwright fixture 可以在浏览器测试前使用 createTestHarness() 启动测试服务器。如果您还想模拟出站 fetch() 请求,也可以同时使用 MSW 拦截。
以下 fixture 设置 Playwright 的 baseURL,向测试公开 MSW 和测试框架,并在每次测试后重置存储状态。
import { test as base, expect } from "@playwright/test";
import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";
import { createTestHarness } from "wrangler";
const test = base.extend({
network: [
async ({}, use) => {
const network = setupServer();
network.listen({ onUnhandledRequest: "error" });
await use(network);
network.close();
},
{ scope: "worker" },
],
server: [
async ({}, use) => {
const server = createTestHarness({
workers: [
{ configPath: "./dist/web_worker/wrangler.json" },
{ configPath: "./dist/api_worker/wrangler.json" },
],
});
await server.listen();
await use(server);
await server.close();
},
{ scope: "worker" },
],
baseURL: async ({ server }, use) => {
const { url } = await server.listen();
await use(url.href);
},
reset: [
async ({ network, server }, use, testInfo) => {
await use();
if (testInfo.status !== testInfo.expectedStatus) {
server.debug();
}
network.resetHandlers();
await server.reset();
},
{ auto: true },
],
});
test("renders a user profile", async ({ page, network }) => {
network.use(
http.get("http://identity.example.com/profile/:id", ({ params }) => {
return HttpResponse.json({ id: params.id, name: "Ada" });
}),
);
await page.goto("/users/123");
await expect(page.getByText("Profile: Ada")).toBeVisible();
});import { test as base, expect } from "@playwright/test";
import { http, HttpResponse } from "msw";
import { setupServer, type SetupServerApi } from "msw/node";
import { createTestHarness, type TestHarness } from "wrangler";
type TestFixtures = {
reset: void;
};
type WorkerFixtures = {
network: SetupServerApi;
server: TestHarness;
};
const test = base.extend<TestFixtures, WorkerFixtures>({
network: [
async ({}, use) => {
const network = setupServer();
network.listen({ onUnhandledRequest: "error" });
await use(network);
network.close();
},
{ scope: "worker" },
],
server: [
async ({}, use) => {
const server = createTestHarness({
workers: [
{ configPath: "./dist/web_worker/wrangler.json" },
{ configPath: "./dist/api_worker/wrangler.json" },
],
});
await server.listen();
await use(server);
await server.close();
},
{ scope: "worker" },
],
baseURL: async ({ server }, use) => {
const { url } = await server.listen();
await use(url.href);
},
reset: [
async ({ network, server }, use, testInfo) => {
await use();
if (testInfo.status !== testInfo.expectedStatus) {
server.debug();
}
network.resetHandlers();
await server.reset();
},
{ auto: true },
],
});
test("renders a user profile", async ({ page, network }) => {
network.use(
http.get("http://identity.example.com/profile/:id", ({ params }) => {
return HttpResponse.json({ id: params.id, name: "Ada" });
}),
);
await page.goto("/users/123");
await expect(page.getByText("Profile: Ada")).toBeVisible();
});