testing

The conformance kit every module runs against. Fake ports, an in-memory database, and no network.

With cargo

cargo add cratefield-testing

What it is

testing.

TestHarness::new takes your modules, fakes every port, applies each module's SQLite migrations to a fresh in-memory database, and assembles the router. It hands back the router and every fake — mailer, captcha, rate limiter, database, clock, KV, HTTP, defer, signer, events, modules, dialect — so a test asserts on what the module did rather than on what it returned.

No network, and no cloud. The default kit is an in-memory SQLite database and fakes, which is what makes the suite the same on a laptop, in CI and inside a Worker build, and why a module can be tested at all before it has anywhere to run. The Postgres feature runs the same tests against a real server, so a module is checked on both dialects in CI. conformance(Box::new(MyModule::new())) is one line and runs the shared rules every module must pass.

Ports

test harness — it fakes all of them

A 15-line module test

conformance(Box::new(MyModule::new())) for the shared rules, then request(&kit.router, POST, "/v1/my-module/join", body) and an assertion on kit.mailer.sent().

History

Changelog.

From the crate’s CHANGELOG.md in the harness, as of 0c5560b. 5 versions recorded, newest first. Every published version is on crates.io.

  1. 0.5.3

    crates.ioReleaseDiff

    Other

    • UrlSafety port in core, with a Google Safe Browsing / Web Risk adapter (#857) (#880)
  2. 0.5.2

    crates.ioReleaseDiff

    Added

    • core Speech port — transcription and streamed synthesis, with Workers AI and OpenAI-compatible adapters (#861) (#868)
    • core HttpClient outbound budgets — per-upstream token buckets, Retry-After backoff, daily quota alerts (#765) (#858)
    • Speech port conformance (issue #861): speech_conformance and speech_conformance_not_configured, with the shared fixture constants, behind the port-conformance feature.
3 earlier versions 0.4.0 to 0.5.1
  1. 0.5.1

    crates.ioReleaseDiff

    Other

    • Actor port: per-key serialized state with transactional storage and alarms, on Durable Objects (#583) (#743)
    • image inputs (Part::Image) for the Anthropic and OpenAI-compatible adapters (#745)
    • Blob port: streamed reads and writes, multipart uploads and listing for objects above MAX_BLOB_BYTES (#586) (#741)

    Added

    • TextModel image inputs (issue #628): the text_model_image_bounds_conformance port suite, and a FakeTextModel that answers image prompts and refuses an over-limit one before recording it.
  2. 0.5.0

    crates.ioReleaseDiff

    Changed

    • Breaking: requires cratefield-core 0.8 (was 0.7), and so a minor rather than a patch bump: a venture still on core 0.7 does not pick this release up through a caret requirement and end up with two copies of core (#712).

    Other

    • tool calling (ToolSpec, tool_calls, run_tool_loop) across the Anthropic and OpenAI-compatible adapters (#665) (#705)
  3. 0.4.0

    crates.ioRelease

    Added

    • testing signed-delivery helpers and Owlpost/Colonizer HTTP fakes (#666) (#686)
    • core breaking name problem type URIs under the venture's own base (#557) (#581)

    Other

    • Blob port: presigned GET and PUT URLs for R2 through the S3 API (SigV4) (#622) (#663)
    • Stream request and response bodies for routes a module declares (#585) (#635)
    • Usage metering: per-subject, per-period counters with an atomic check-and-increment (#588) (#634)
    • CustomHostnames port in core, with a Cloudflare for SaaS adapter (#590) (#630)
    • comment op, inbound status webhooks, Freshdesk destination and the Jira Cloud adapter (#559, part 1) (#582)
    • VectorIndex and Embedder ports, with Cloudflare Vectorize and exact in-process adapters (#561) (#568)
    • OpenAI-compatible adapter, cached-token usage on every completion, shared TextModel conformance suite (#560) (#567)

Public and private modules run the same kit.