Cloudflare Docs
Workers
Edit this page on GitHub
Set theme to dark (⇧+D)

Configuration

The Workers Vitest integration provides additional configuration on top of Vitest’s usual options. To configure the Workers Vitest integration, use the poolOptions.workers key. Use the defineWorkersConfig() function from the @cloudflare/vitest-pool-workers/config module for type checking and completions.

An example configuration would be:

vitest.config.ts
import { defineWorkersConfig } from "@cloudflare/vitest-pool-workers/config";
export default defineWorkersConfig({
test: {
poolOptions: {
workers: {
wrangler: {
configPath: "./wrangler.toml"
},
},
},
},
});

​​ Functions

The following functions are exported from the @cloudflare/vitest-pool-workers/config module.

  • defineWorkersConfig(options:UserConfig & { test?: { poolOptions?: { workers?: WorkersPoolOptions | ((ctx: WorkerPoolOptionsContext) => Awaitable<WorkersPoolOptions>) } } })

    • Ensures Vitest is configured to use the Workers integration with the correct module resolution settings, and provides type checking for WorkersPoolOptions. This should be used in place of the defineConfig() function from Vitest. The defineWorkersConfig() function also accepts a Promise of options, or an optionally-async function returning options.
  • defineWorkersProject(options:UserWorkspaceConfig & { test?: { poolOptions?: { workers?: WorkersPoolOptions | ((ctx: WorkerPoolOptionsContext) => Awaitable<WorkersPoolOptions>) } } })

    • Ensures Vitest is configured to use the Workers integration with the correct module resolution settings, and provides type checking for WorkersPoolOptions. This should be used in place of the defineProject() function from Vitest. The defineWorkersProject() function also accepts a Promise of options, or an optionally-async function returning options.
  • readD1Migrations(migrationsPath:string): D1Migration[]

​​ WorkersPoolOptions

  • main: stringoptional

    • Entry point to Worker run in the same isolate/context as tests. This option is required to use import { SELF } from "cloudflare:test" for integration tests, or Durable Objects without an explicit scriptName if classes are defined in the same Worker. This file goes through Vite transforms and can be TypeScript. Note that import module from "<path-to-main>" inside tests gives exactly the same module instance as is used internally for the SELF and Durable Object bindings. If wrangler.configPath is defined and this option is not, it will be read from the main field in that configuration file.
  • isolatedStorage: booleanoptional

    • Enables per-test isolated storage. If enabled, any writes to storage performed in a test will be undone at the end of the test. The test’s storage environment is copied from the containing suite, meaning beforeAll() hooks can be used to seed data. If this option is disabled, all tests will share the same storage. .concurrent tests are not supported when isolated storage is enabled. Refer to the Isolation and concurrency page for more information on the isolation model.

    • Defaults to true.

      Illustrative example
      import { env } from "cloudflare:test";
      import { beforeAll, beforeEach, describe, test, expect } from "vitest";
      // Get the current list stored in a KV namespace
      async function get(): Promise<string[]> {
      return await env.NAMESPACE.get("list", "json") ?? [];
      }
      // Add an item to the end of the list
      async function append(item: string) {
      const value = await get();
      value.push(item);
      await env.NAMESPACE.put("list", JSON.stringify(value));
      }
      beforeAll(() => append("all"));
      beforeEach(() => append("each"));
      test("one", async () => {
      // Each test gets its own storage environment copied from the parent
      await append("one");
      expect(await get()).toStrictEqual(["all", "each", "one"]);
      });
      // `append("each")` and `append("one")` undone
      test("two", async () => {
      await append("two");
      expect(await get()).toStrictEqual(["all", "each", "two"]);
      });
      // `append("each")` and `append("two")` undone
      describe("describe", async () => {
      beforeAll(() => append("describe all"));
      beforeEach(() => append("describe each"));
      test("three", async () => {
      await append("three");
      expect(await get()).toStrictEqual([
      // All `beforeAll()`s run before `beforeEach()`s
      "all", "describe all", "each", "describe each", "three"
      ]);
      });
      // `append("each")`, `append("describe each")` and `append("three")` undone
      test("four", async () => {
      await append("four");
      expect(await get()).toStrictEqual([
      "all", "describe all", "each", "describe each", "four"
      ]);
      });
      // `append("each")`, `append("describe each")` and `append("four")` undone
      });
  • singleWorker: booleanoptional

    • Runs all tests in this project serially in the same Worker, using the same module cache. This can significantly speed up execution if you have lots of small test files. Refer to the Isolation and concurrency page for more information on the isolation model.

    • Defaults to false.

  • miniflare: SourcelessWorkerOptions & { workers?: WorkerOptions[]; }optional

    • Use this to provide configuration information that is typically stored within the Wrangler configuration file, such as bindings, compatibility dates, and compatibility flags. The WorkerOptions interface is defined here. Use the main option above to configure the entry point, instead of the Miniflare script, scriptPath, or modules options.

    • If your project makes use of multiple Workers, you can configure auxiliary Workers that run in the same workerd process as your tests and can be bound to. Auxiliary Workers are configured using the workers array, containing regular Miniflare WorkerOptions objects. Note that unlike the main Worker, auxiliary Workers:

  • wrangler: { configPath?: string; }optional

    • Path to Wrangler configuration file to load main, compatibility settings and bindings from. These options will be merged with the miniflare option above, with miniflare values taking precedence. For example, if your Wrangler configuration defined a service binding named SERVICE to a Worker named service, but you included serviceBindings: { SERVICE(request) { return new Response("body"); } } in the miniflare option, all requests to SERVICE in tests would return body. Note configPath accepts both .toml and .json files.

​​ WorkersPoolOptionsContext

  • inject: typeof import(“vitest”).inject

    • The same inject() function usually imported from the vitest module inside tests. This allows you to define miniflare configuration based on injected values from globalSetup scripts. Use this if you have a value in your configuration that is dynamically generated and only known at runtime of your tests. For example, a global setup script might start an upstream server on a random port. This port could be provide()d and then inject()ed in the configuration for an external service binding or Hyperdrive. Refer to the Hyperdrive recipe for an example project using this provide/inject approach.

      Illustrative example
      // env.d.ts
      declare module "vitest" {
      interface ProvidedContext {
      port: number;
      }
      }
      // global-setup.ts
      import type { GlobalSetupContext } from "vitest/node";
      export default function ({ provide }: GlobalSetupContext) {
      // Runs inside Node.js, could start server here...
      provide("port", 1337);
      return () => { /* ...then teardown here */ };
      }
      // vitest.config.ts
      import { defineWorkersConfig } from "@cloudflare/vitest-pool-workers/config";
      export default defineWorkersConfig({
      test: {
      globalSetup: ["./global-setup.ts"],
      pool: "@cloudflare/vitest-pool-workers",
      poolOptions: {
      workers: ({ inject }) => ({
      miniflare: {
      hyperdrives: {
      DATABASE: `postgres://user:pass@example.com:${inject("port")}/db`,
      },
      },
      }),
      },
      },
      });

​​ SourcelessWorkerOptions

Sourceless WorkerOptions type without script, scriptPath, or modules properties. Refer to the Miniflare WorkerOptions type for more details.

type SourcelessWorkerOptions = Omit<
WorkerOptions,
"script" | "scriptPath" | "modules" | "modulesRoot"
>;