Open the right binding testing guide instead of reconstructing the test story from scratch
Every binding overview page already links a hidden testing guide. This page collects those guides in one place so you can jump straight to the right harness, caveats, and escalation path for the binding that changed.
Binding testing is not one-size-fits-all. KV, D1, R2, Durable Objects, Queues, and several other bindings are strong local-first stories, while AI, Vectorize, and a few infrastructure-heavy bindings need more remote or higher-fidelity checks sooner. Use this page when you know the binding but do not want to hunt through the whole binding library first.
- Best for
- Jumping straight to the right binding-specific testing guide
- Where the links also live
- At the bottom of each binding overview page
- Default pattern
- Usually plus the real binding or helper surface
- Notable exceptions
- AI and Vectorize are remote-oriented, and some other bindings need higher-fidelity checks sooner
Use this page as the index, but remember where the links already live
The binding library intentionally keeps only the main binding overview pages visible in the sidebar. The testing pages are still real docs pages, but they stay linked from the bottom of each binding overview so the sidebar does not turn into a twelve-level nesting doll.
That is great once you already opened the right binding page. This index is for the opposite moment: you know the binding that changed and you want the testing guide immediately.
- Open the binding overview page first when you need authoring, runtime, or preview context before the tests make sense.
- Open the testing guide first when the binding already exists and the only remaining question is how to test it.
- Use when you need the bigger map across starter tests, harness behavior, binding guides, runtime helpers, and automation.
Open the testing guide for the binding that actually changed
Binding guide
Testing KV
`createTestContext()` plus `env.CACHE` or `cf.worker.fetch()`Use the default test harness first. KV is one of the bindings Devflare supports best in local tests. Open the KV overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing D1
`createTestContext()` with `env.DB` or `cf.worker.fetch()`D1 is one of the easiest bindings to test meaningfully with Devflare because the local runtime already speaks the same database API your worker uses. Open the D1 overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing R2
`createTestContext()` with `env.ASSETS` or `cf.worker.fetch()`R2 is local-friendly, which means you can test real object operations without inventing a storage adapter just to get off the ground. Open the R2 overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Durable Objects
`createTestContext()` with the real DO namespace in `env`Durable Objects are well-supported in the default Devflare harness, which means you can test real object behavior without hand-building a fake namespace first. Open the Durable Objects overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Queues
`createTestContext()` plus `cf.queue.trigger()`Queue testing is one of the places where Devflare’s helper surface feels especially good because the queue trigger already knows how to drive the real handler shape. Open the Queues overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Services
`createTestContext()` plus `env.MY_SERVICE`Service bindings are one of the clearest Devflare wins in multi-worker apps: you can keep the real worker boundary and still prove it through the default local harness. Open the Services overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing AI
`createTestContext()` after remote mode is enabled, plus `shouldSkip.ai`The right AI test strategy is selective: use remote mode when you mean to test inference, and skip cleanly when the environment is not allowed to do that. Open the AI overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Vectorize
`createTestContext()` in remote mode plus `shouldSkip.vectorize`The right Vectorize tests are targeted remote checks: a small insert or query, a clear skip condition, and a real index behind the binding. Open the Vectorize overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Hyperdrive
`createTestContext()` or `createOfflineEnv()` with `localConnectionString`Hyperdrive testing should start with a local connection string, then add a focused query test against the database shape your app actually uses. Open the Hyperdrive overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Browser Rendering
A narrow browser route exercised through the dev server, a preview URL, or another integration-style pathBrowser tests should usually be integration-flavored: either drive the worker in dev or exercise a thin smoke path that proves the binding can launch and fetch. Open the Browser Rendering overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Analytics Engine
A thin worker test or explicit mock around `writeDataPoint()`Analytics Engine tests should stay thin: verify that the worker writes a data point, not that you can recreate Cloudflare analytics locally. Open the Analytics Engine overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Send Email
`createTestContext()` plus `env.TRANSACTIONAL_EMAIL.send(...)`Send Email is stronger locally than many platform-service bindings because outbound email can be exercised in the default harness, while inbound email has its own related helper surface. Open the Send Email overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Rate Limiting
`createTestContext()` or `createOfflineEnv()`Test Rate Limiting by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the Rate Limiting overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Version Metadata
`createTestContext()` or `createOfflineEnv()`Test Version Metadata by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the Version Metadata overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Worker Loaders
`createTestContext()` with explicit Worker payloads or a pure stubTest Worker Loaders by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the Worker Loaders overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Secrets Store
`createTestContext()` or `createOfflineEnv(config, fixtures, { cwd })`Test Secrets Store by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the Secrets Store overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing AI Search
`createOfflineEnv()` with AI Search fixturesTest AI Search by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the AI Search overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing mTLS Certificates
`createOfflineEnv()` with `fixtures.mtlsCertificates`Test mTLS Certificates by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the mTLS Certificates overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Dispatch Namespaces
`createOfflineEnv()` with `fixtures.dispatchNamespaces`Test Dispatch Namespaces by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the Dispatch Namespaces overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Workflows
`createTestContext()` or `createOfflineEnv()`Test Workflows by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the Workflows overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Pipelines
`createTestContext()` or `createOfflineEnv()`Test Pipelines by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the Pipelines overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Images
`createTestContext()` or `createOfflineEnv()`Test Images by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the Images overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Media Transformations
`createTestContext()` or `createOfflineEnv()` with media fixturesTest Media Transformations by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the Media Transformations overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Artifacts
`createOfflineEnv()` with artifact fixturesTest Artifacts by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the Artifacts overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
Binding guide
Testing Containers
`devflare/test` containers helpers guarded by `shouldSkip.containers`Test Containers by choosing the local harness that matches the product boundary instead of reaching for Cloudflare by default. Open the Containers overview first when you need the full binding story, or jump straight here when the only open question is how to test it.
The testing posture is not identical for every binding
| Binding | Testing posture | Default harness |
|---|---|---|
| KV | Local runtime and tests | plus or |
| D1 | Local runtime and tests | with or |
| R2 | Local runtime and tests | with or |
| Durable Objects | Local runtime and tests, including cross-worker references | with the real DO namespace in |
| Queues | Local runtime and queue-trigger tests | plus |
| Services | Local runtime and multi-worker tests | plus |
| AI | Remote-oriented; local tests require remote mode | after remote mode is enabled, plus |
| Vectorize | Remote-oriented; local tests require remote mode or explicit mocks | in remote mode plus |
| Hyperdrive | Full local support when Devflare has a local database connection string for the binding | or with |
| Browser Rendering | Supported, but the strongest story is dev server and integration rather than a dedicated test helper | A narrow browser route exercised through the dev server, a preview URL, or another integration-style path |
| Analytics Engine | Supported, but usually tested through integration or thin mocks | A thin worker test or explicit mock around |
| Send Email | Outbound local support; distinct from inbound email event testing | plus |
| Rate Limiting | Offline-native: Miniflare and Devflare pure mocks can exercise application-level rate limit behavior | or |
| Version Metadata | Offline-native: Devflare can provide deterministic local metadata without Cloudflare state | or |
| Worker Loaders | Full local support through Miniflare Worker Loader bindings and explicit pure-test Worker stubs | with explicit Worker payloads or a pure stub |
| Secrets Store | Full local support through Miniflare wiring, local values, and explicit fixture values for pure tests | or |
| AI Search | Offline-fixture: deterministic in-memory instances can test application flow, not hosted relevance behavior | with AI Search fixtures |
| mTLS Certificates | Offline-fixture: local tests can model Fetcher behavior, but not real certificate presentation | with |
| Dispatch Namespaces | Offline-fixture: tests can provide named tenant fetchers, but Devflare does not emulate tenant upload/lifecycle | with |
| Workflows | Full local support through Miniflare workflow bindings and deterministic workflow mocks | or |
| Pipelines | Offline-native for send-recording tests; Cloudflare owns production batching and sink delivery | or |
| Images | Full local support through Miniflare image bindings, persisted local state, and deterministic pure mocks | or |
| Media Transformations | Full local support through Miniflare media bindings and deterministic pure mocks for transform chains | or with media fixtures |
| Artifacts | Offline-fixture: repo metadata and token flows can be modeled in memory, not as real Git remotes | with artifact fixtures |
| Containers | Offline-native only when an explicit Docker/Podman engine is available and the image can run without pulling | containers helpers guarded by |
Different defaults are a good thing
KV, D1, R2, and Queues should not be documented like remote AI inference, and remote AI inference should not be documented like local KV. The different testing guides are there to keep those truths visible.
Copy the smallest helper that matches the boundary
Pick the helper from the thing you need to prove. Use pure mocks for small functions, when config-derived binding names matter, when the Worker surface matters, and skip-gated lanes when Docker/Podman or Cloudflare credentials are part of the test.
| Need to prove | Start with | Runs in ordinary CI? |
|---|---|---|
| A pure function calls one binding method | or a specific helper | Yes |
| The env should match without booting Miniflare | Yes | |
| A Worker route, queue, scheduled, email, tail, or service flow works | plus | Yes, unless the feature itself needs a remote boundary |
| Docker/Podman, Cloudflare auth, or deployed behavior is the point | plus a separate integration lane | Only when the runner has the dependency |
Four helper lanes in one test file
Previous
createTestContext()
Start tests with so the same config, bindings, routes, and handler surfaces the app uses in real runtime flows are available in Bun tests.
Next
Test helper reference
Use this reference when you know you need the test package but not which helper surface is the smallest truthful proof.