← Cloudflare Workers / workers / testing / test-harness
Integrace
Můžete použít createTestHarness() se stávajícími nástroji v ekosystému Node.js. Příklady na této stránce ukazují běžné vzory integrace, které si můžete přizpůsobit pro vlastní testovací prostředí.
Mock Service Worker
Pokud váš Worker vytváří odchozí fetch() požadavky můžete použít Mock Service Worker (MSW) ↗ k jejich zachycení a vrácení předvídatelných odpovědí. MSW poskytuje znovupoužitelné obslužné rutiny požadavků, které lze sdílet napříč testy.
Můžete například spustit MSW ještě před testy, odmítat neošetřené požadavky a po každém testu resetovat handlery:
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" });
});Playwright
Pokud vytváříte webovou aplikaci a chcete ověřit uživatelské scénáře ve skutečném prohlížeči, použijte Playwright ↗ s testovacím rámcem. Playwright dokáže procházet stránky, komunikovat s uživatelským rozhraním a ověřovat chování vašeho projektu Workers od začátku do konce.
Fixture Playwright dokáže spustit testovací server pomocí createTestHarness() před testy v prohlížeči. Pokud chcete simulovat odchozí fetch() požadavky můžete také použít MSW k jejich současnému zachycení.
Následující fixture nastavuje Playwright baseURL, zpřístupní testům MSW a testovací framework a po každém testu resetuje stav úložiště.
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();
});