← Cloudflare Workers / workers / testing / vitest-integration
Napište svůj první test
Tento průvodce vysvětluje, jak začít s @cloudflare/vitest-plugin balíček. Složitější příklady testování s @cloudflare/vitest-plugin, přečtěte si Recepty.
Předpoklady
Nejprve se ujistěte, že:
-
Váš compatibility date je nastaveno na
2022-10-31nebo novější. -
Váš Worker používající formát ES modulů (pokud ne, přečtěte si migrace na formát ES modulů průvodce).
-
Vitest a
@cloudflare/vitest-pluginjsou ve vašem projektu nainstalovány jako vývojové závislostinpm i -D vitest@^4.1.0 @cloudflare/vitest-plugin
Definujte konfiguraci Vitest
Ve vašem vitest.config.ts soubor, použijte cloudflareTest() plugin pro konfiguraci integrace Workers Vitest.
Konfiguraci svého Workeru můžete použít z Konfigurační soubor Wrangleru jeho zadáním pomocí wrangler.configPath.
import { cloudflareTest } from "@cloudflare/vitest-plugin";
import { defineConfig } from "vitest/config";
export default defineConfig({
plugins: [
cloudflareTest({
wrangler: { configPath: "./wrangler.jsonc" },
}),
],
});Další konfiguraci můžete také přepsat nebo definovat pomocí miniflare klíč. Ten má přednost před hodnotami nastavenými v konfiguraci Wrangleru.
Tato konfigurace by například přidala KV namespace TEST_NAMESPACE ke kterému se přistupovalo a který byl upravován pouze v testech.
export default defineConfig({
plugins: [
cloudflareTest({
wrangler: { configPath: "./wrangler.jsonc" },
miniflare: {
kvNamespaces: ["TEST_NAMESPACE"],
},
}),
],
});Úplný seznam dostupných možností Miniflare najdete v Miniflare WorkersOptions dokumentace API ↗.
Úplný seznam dostupných konfiguračních možností najdete v Konfigurace.
Definujte typy
Pokud nepoužíváte Typescript, tuto část můžete přeskočit.
Nejprve se ujistěte, že jste spustili wrangler types, který generuje typy pro runtime Cloudflare Workers a Env typu na základě vazeb vašeho Workeru.
Poté přidejte tsconfig.json ve vaší složce testů a přidejte "@cloudflare/vitest-plugin" do pole types, abyste definovali typy pro cloudflare:test.
Rovněž byste měli přidat výstup wrangler types do include pole, aby byly k dispozici typy pro runtime Cloudflare Workers.
Příklad test/tsconfig.json
{
"extends": "../tsconfig.json",
"compilerOptions": {
"moduleResolution": "bundler",
"types": [
"@cloudflare/vitest-plugin/types", // provides `cloudflare:test` and `cloudflare:workers` types
],
},
"include": [
"./**/*.ts",
"../src/worker-configuration.d.ts", // output of `wrangler types`
],
}Psaní testů
Jako příklad použijeme tento jednoduchý Worker. Vrací odpověď 404 pro /404 cestu a "Hello World!" pro všechny ostatní cesty.
export default {
async fetch(request, env, ctx) {
if (pathname === "/404") {
return new Response("Not found", { status: 404 });
}
return new Response("Hello World!");
},
};export default {
async fetch(request, env, ctx): Promise<Response> {
if (pathname === "/404") {
return new Response("Not found", { status: 404 });
}
return new Response("Hello World!");
},
} satisfies ExportedHandler<Env>;Jednotkové testy
Importem Workeru můžeme napsat unit test pro jeho fetch handler.
import { env } from "cloudflare:workers";
import {
createExecutionContext,
waitOnExecutionContext,
} from "cloudflare:test";
import { describe, it, expect } from "vitest";
// Import your worker so you can unit test it
import worker from "../src";
// For now, you'll need to do something like this to get a correctly-typed
// `Request` to pass to `worker.fetch()`.
const IncomingRequest = Request;
describe("Hello World worker", () => {
it("responds with Hello World!", async () => {
const request = new IncomingRequest("http://example.com/404");
// Create an empty context to pass to `worker.fetch()`
const ctx = createExecutionContext();
const response = await worker.fetch(request, env, ctx);
// Wait for all `Promise`s passed to `ctx.waitUntil()` to settle before running test assertions
await waitOnExecutionContext(ctx);
expect(response.status).toBe(404);
expect(await response.text()).toBe("Not found");
});
});import { env } from "cloudflare:workers";
import {
createExecutionContext,
waitOnExecutionContext,
} from "cloudflare:test";
import { describe, it, expect } from "vitest";
// Import your worker so you can unit test it
import worker from "../src";
// For now, you'll need to do something like this to get a correctly-typed
// `Request` to pass to `worker.fetch()`.
const IncomingRequest = Request<unknown, IncomingRequestCfProperties>;
describe("Hello World worker", () => {
it("responds with Hello World!", async () => {
const request = new IncomingRequest("http://example.com/404");
// Create an empty context to pass to `worker.fetch()`
const ctx = createExecutionContext();
const response = await worker.fetch(request, env, ctx);
// Wait for all `Promise`s passed to `ctx.waitUntil()` to settle before running test assertions
await waitOnExecutionContext(ctx);
expect(response.status).toBe(404);
expect(await response.text()).toBe("Not found");
});
});Integrační testy
Můžete použít exports objekt poskytovaný cloudflare:workers k napsání integračního testu. exports.default.fetch() volá výchozí exportovaný handler definovaný v hlavním Workeru.
import { exports } from "cloudflare:workers";
import { describe, it, expect } from "vitest";
describe("Hello World worker", () => {
it("responds with not found and proper status for /404", async () => {
const response = await exports.default.fetch("http://example.com/404");
expect(response.status).toBe(404);
expect(await response.text()).toBe("Not found");
});
});import { exports } from "cloudflare:workers";
import { describe, it, expect } from "vitest";
describe("Hello World worker", () => {
it("responds with not found and proper status for /404", async () => {
const response = await exports.default.fetch("http://example.com/404");
expect(response.status).toBe(404);
expect(await response.text()).toBe("Not found");
});
});Při použití exports.default.fetch() pro integrační testy běží kód vašeho Workeru ve stejném kontextu jako test runner. To znamená, že pro ovládání Workeru můžete použít globální mocky, ale zároveň to znamená, že váš Worker používá mírně odlišné chování při rozlišování modulů, které poskytuje Vite.
Ve většině případů to není problém, ale pokud chcete Workera spustit v čistém prostředí co nejbližším produkčnímu, můžete použít pomocný Worker. Více informací najdete v tento příklad ↗ o tom, jak nastavit integrační testy pomocí pomocných Workerů. Použití pomocných Workerů však přináší omezení o kterých byste měli vědět.
Související zdroje
- Složitější příklady testování s
@cloudflare/vitest-plugin, přečtěte si Recepty. - Referenční dokumentace ke konfiguračnímu API
- Referenční příručka Testovací API