Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

連携

最終更新 Markdown で表示Agent セットアップ

createTestHarness() は、Node.js エコシステムの既存ツールと一緒に使えます。このページの例は、テスト環境に合わせて応用できる一般的な連携パターンです。

Mock Service Worker

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" });
});

Playwright

Web アプリケーションを作っていて、実際のブラウザでユーザーフローを確認したい場合は、テストハーネスと一緒に Playwright を使います。Playwright はページを開き、ユーザーインターフェイスを操作し、Workers プロジェクトの動作をエンドツーエンドで確認できます。

Playwright のフィクスチャは、ブラウザテストの前に createTestHarness() でテストサーバーを起動できます。アウトバウンドの fetch() リクエストをモックしたい場合は、同時に MSW でインターセプトすることもできます。

次のフィクスチャは Playwright の baseURL を設定し、MSW とテストハーネスをテストへ公開し、各テスト後にストレージ状態をリセットします。

tests/playwright.test.jsjs
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();
});
tests/playwright.test.tsts
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();
});

役に立ちましたか?