INTEGRITY Dokumentace

Známé problémy

Plugin Workers Vitest má následující známé problémy:

Pokrytí

Nativní pokrytí kódu prostřednictvím V8 není podporováno. Musíte použít instrumentované pokrytí kódu prostřednictvím Istanbul místo toho. Viz Dokumentace Vitest Coverage pro pokyny k nastavení.

Falešné časovače

Vitest fake timers se nevztahují na simulátory KV, R2 a mezipaměti. Nelze například nechat vypršet klíč KV posunutím falešného času.

Dynamic import() příkazy s exports a Durable Objects

Dynamic import() příkazy nefungují uvnitř export default { ... } handlery při psaní integračních testů s exports.default.fetch(), nebo uvnitř obslužných rutin událostí Durable Object. Své obslužné rutiny musíte importovat a volat přímo, nebo použít statické import příkazy v globálním rozsahu.

WebSockets

Používání WebSockets s Durable Objects není podporováno při izolaci úložiště po jednotlivých souborech. Tento problém obejdete spuštěním testů se sdíleným úložištěm pomocí --max-workers=1 --no-isolate.

Izolace úložiště

Izolace úložiště je podle testovacího souboru. Spouštěč testů na konci každého testovacího souboru vrátí zpět všechny zápisy do úložiště, jak je popsáno v dokumentace k izolaci a souběžnosti. Cloudflare doporučuje následující kroky, kterými se vyhnete běžným problémům:

Počkejte na dokončení všech operací s úložištěm

Vždy await všechny Promises, které čtou nebo zapisují do úložných služeb.

// Example: Seed data
beforeAll(async () => {
	await env.KV.put("message", "test message");
	await env.R2.put("file", "hello-world");
});

Explicitně signalizujte uvolnění prostředku

Při volání RPC metod Service Workeru nebo Durable Object, které vrací neprimitivní hodnoty (například objekty nebo třídy rozšiřující RpcTarget), použijte using klíčové slovo, kterým explicitně signalizujete, kdy lze prostředky uvolnit. Viz tento ukázkový test a viz explicit-resource-management pro další podrobnosti.

using result = await stub.getCounter();

Zpracujte těla odpovědí

Při vytváření požadavků přes fetch nebo R2.get(), spotřebujte celé tělo odpovědi, i když neověřujete jeho obsah. Například:

test("check if file exists", async () => {
	await env.R2.put("file", "hello-world");
	const response = await env.R2.get("file");

	expect(response).not.toBe(null);
	// Consume the response body even if you are not asserting it
	await response.text();
});

Chybějící vlastnosti u ctx.exports

ctx.exports vlastnost poskytuje přístup k exportům hlavního Workeru. Integrace Workers Vitest se pokouší tyto exporty automaticky odvodit statickou analýzou zdrojového kódu Workeru pomocí nástroje esbuild. Složitější sestavení, například používající virtuální moduly nebo zástupné reexporty (wildcard), které esbuild nedokáže sledovat, však mohou způsobit, že na ctx.exports objekt.

Uvažujme například Worker, který pomocí wildcard exportu znovu exportuje entrypoint z virtuálního modulu:

// index.ts
export * from "@virtual-module";

V tomto případě jakékoli exporty z @virtual-module (například MyEntrypoint) nelze automaticky odvodit, a proto bude chybět v ctx.exports.

Chcete-li to obejít, přidejte additionalExports možnost do konfigurace Vitest:

import { cloudflareTest } from "@cloudflare/vitest-plugin";
import { defineConfig } from "vitest/config";

export default defineConfig({
	plugins: [
		cloudflareTest({
			wrangler: { configPath: "./wrangler.jsonc" },
			additionalExports: {
				MyEntrypoint: "WorkerEntrypoint",
			},
		}),
	],
});

additionalExports možnost je mapa, kde klíče jsou názvy exportů a hodnoty typ exportu ("WorkerEntrypoint", "DurableObject", nebo "WorkflowEntrypoint").

Rozlišování modulů

Pokud narazíte na problémy s rozpoznáváním modulů, například: Error: Cannot use require() to import an ES Module nebo Error: No such module, tyto závislosti můžete sloučit do balíčku pomocí deps.optimizer možnost:

import { cloudflareTest } from "@cloudflare/vitest-plugin";
import { defineConfig } from "vitest/config";

export default defineConfig({
	plugins: [
		cloudflareTest({
			// ...
		}),
	],
	test: {
		deps: {
			optimizer: {
				ssr: {
					enabled: true,
					include: ["your-package-name"],
				},
			},
		},
	},
});

Příklad najdete v Recepty stránce.

Import modulů z globálního souboru pro nastavení

Ačkoli je Vitest nastaven tak, aby řešil balíčky pro workerd runtime spustí váš globální setup soubor v prostředí Node.js. To může způsobit problémy při importu balíčků, jako je Postgres.js, který exportuje verzi bez Node pro workerd. Jako řešení můžete vytvořit wrapper, který pomocí SSR module loaderu Vite importuje globální soubor nastavení za správných podmínek. Poté upravte konfiguraci Vitestu tak, aby odkazovala na tento wrapper. Například:

// File: global-setup-wrapper.ts
import { createServer } from "vite";

// Import the actual global setup file with the correct setup
const mod = await viteImport("./global-setup.ts");

export default mod.default;

// Helper to import the file with default node setup
async function viteImport(file: string) {
	const server = await createServer({
		root: import.meta.dirname,
		configFile: false,
		server: { middlewareMode: true, hmr: false, watch: null, ws: false },
		optimizeDeps: { noDiscovery: true },
		clearScreen: false,
	});
	const mod = await server.ssrLoadModule(file);
	await server.close();
	return mod;
}
// File: vitest.config.ts
import { cloudflareTest } from "@cloudflare/vitest-plugin";
import { defineConfig } from "vitest/config";

export default defineConfig({
	plugins: [
		cloudflareTest({
			// ...
		}),
	],
	test: {
		// Replace the globalSetup with the wrapper file
		globalSetup: ["./global-setup-wrapper.ts"],
	},
});