Known issues
The Workers Vitest pool is currently in open beta. The following are issues Cloudflare is aware of and fixing:
Native code coverage via V8 ↗ is not supported. You must use instrumented code coverage via Istanbul ↗ instead. Refer to the Vitest Coverage documentation ↗ for setup instructions.
Vitest's fake timers ↗ do not apply to KV, R2 and cache simulators. For example, you cannot expire a KV key by advancing fake time.
Dynamic import()
statements do not work inside export default { ... }
handlers when writing integration tests with SELF
, or inside Durable Object event handlers. You must import and call your handlers directly, or use static import
statements in the global scope.
Durable Object alarms are not reset between test runs and do not respect isolated storage. Ensure you delete or run all alarms with runDurableObjectAlarm()
scheduled in each test before finishing the test.
Using WebSockets with Durable Objects with the isolatedStorage
flag turned on is not supported. You must set isolatedStorage: false
in your vitest.config.ts
file.
When the isolatedStorage
flag is enabled (the default), the test runner will undo any writes to the storage at the end of the test as detailed in the isolation and concurrency documentation. However, Cloudflare recommends that you consider the following actions to avoid any common issues:
Always await
all Promise
s that read or write to storage services.
// Example: Seed databeforeAll(async () => { await env.KV.put('message', 'test message'); await env.R2.put('file', 'hello-world');});
When calling RPC methods of a Service Worker or Durable Object that return non-primitive values (such as objects or classes extending RpcTarget
), use the using
keyword to explicitly signal when resources can be disposed of. See this example test ↗ and refer to explicit-resource-management for more details.
using result = await stub.getCounter();
When making requests via fetch
or R2.get()
, consume the entire response body, even if you are not asserting its content. For example:
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()});
If you encounter module resolution issues such as: Error: Cannot use require() to import an ES Module
or Error: No such module
, you can bundle these dependencies using the deps.optimizer ↗ option:
import { defineWorkersConfig } from "@cloudflare/vitest-pool-workers/config";
export default defineWorkersConfig({ test: { deps: { optimizer: { ssr: { enabled: true, include: ["your-package-name"], }, }, }, poolOptions: { workers: { // ... }, }, },});
You can find an example in the Recipes page.
Although Vitest is set up to resolve packages for the workerd
runtime, it runs your global setup file in the Node.js environment. This can cause issues when importing packages like Postgres.js ↗, which exports a non-Node version for workerd
.
To work around this, you can create a wrapper that uses Vite's SSR module loader to import the global setup file under the correct conditions. Then, adjust your Vitest configuration to point to this wrapper. For example:
// File: global-setup-wrapper.tsimport { createServer } from "vite"
// Import the actual global setup file with the correct setupconst mod = await viteImport("./global-setup.ts")
export default mod.default;
// Helper to import the file with default node setupasync 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.tsimport { defineWorkersConfig } from "@cloudflare/vitest-pool-workers/config";
export default defineWorkersConfig({ test: { // Replace the globalSetup with the wrapper file globalSetup: ["./global-setup-wrapper.ts"], poolOptions: { workers: { // ... }, }, },});
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Products
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark