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.tsimport { 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 thedefineConfig()
function from Vitest. ThedefineWorkersConfig()
function also accepts aPromise
ofoptions
, or an optionally-async
function returningoptions
.
- Ensures Vitest is configured to use the Workers integration with the correct module resolution settings, and provides type checking for
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 thedefineProject()
function from Vitest. ThedefineWorkersProject()
function also accepts aPromise
ofoptions
, or an optionally-async
function returningoptions
.
- Ensures Vitest is configured to use the Workers integration with the correct module resolution settings, and provides type checking for
readD1Migrations(migrationsPath:string)
:D1Migration[]
- Reads all D1 migrations stored at
migrationsPath
and returns them ordered by migration number. Each migration will have its contents split into an array of individual SQL queries. Call theapplyD1Migrations()
function inside a test or setup file to apply migrations. Refer to the D1 recipe for an example project using migrations.
- Reads all D1 migrations stored at
WorkersPoolOptions
main
:string
- 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 explicitscriptName
if classes are defined in the same Worker. This file goes through Vite transforms and can be TypeScript. Note thatimport module from "<path-to-main>"
inside tests gives exactly the samemodule
instance as is used internally for theSELF
and Durable Object bindings. Ifwrangler.configPath
is defined and this option is not, it will be read from themain
field in that configuration file.
- Entry point to Worker run in the same isolate/context as tests. This option is required to use
isolatedStorage
:boolean
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 namespaceasync function get(): Promise<string[]> {return await env.NAMESPACE.get("list", "json") ?? [];}// Add an item to the end of the listasync 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 parentawait append("one");expect(await get()).toStrictEqual(["all", "each", "one"]);});// `append("each")` and `append("one")` undonetest("two", async () => {await append("two");expect(await get()).toStrictEqual(["all", "each", "two"]);});// `append("each")` and `append("two")` undonedescribe("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")` undonetest("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
:boolean
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[]; }
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 themain
option above to configure the entry point, instead of the Miniflarescript
,scriptPath
, ormodules
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 theworkers
array, containing regular MiniflareWorkerOptions
objects. Note that unlike themain
Worker, auxiliary Workers:- Cannot have TypeScript entrypoints. You must compile auxiliary Workers to JavaScript first. You can use the
wrangler deploy --dry-run --outdir dist
command for this. - Use regular Workers module resolution semantics. Refer to the Isolation and concurrency page for more information.
- Cannot access the
cloudflare:test
module. - Do not require specific compatibility dates or flags.
- Can be written with the Service Worker syntax.
- Are not affected by global mocks defined in your tests.
- Cannot have TypeScript entrypoints. You must compile auxiliary Workers to JavaScript first. You can use the
wrangler
:{ configPath?: string; }
- Path to Wrangler configuration file to load
main
, compatibility settings and bindings from. These options will be merged with theminiflare
option above, withminiflare
values taking precedence. For example, if your Wrangler configuration defined a service binding namedSERVICE
to a Worker namedservice
, but you includedserviceBindings: { SERVICE(request) { return new Response("body"); } }
in theminiflare
option, all requests toSERVICE
in tests would returnbody
. NoteconfigPath
accepts both.toml
and.json
files.
- Path to Wrangler configuration file to load
WorkersPoolOptionsContext
inject
:typeof import(“vitest”).inject
The same
inject()
function usually imported from thevitest
module inside tests. This allows you to defineminiflare
configuration based on injected values fromglobalSetup
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 beprovide()
d and theninject()
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.tsdeclare module "vitest" {interface ProvidedContext {port: number;}}// global-setup.tsimport 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.tsimport { 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"
>;