cratefield-testing
The conformance kit every Factory Zero module runs against — public and
private modules alike. Fake ports, an in-memory SQLite Database, and
request helpers over the axum router with no network.
A 15-line module test
use ;
async
What you get
TestHarness::new(vec![Box<dyn Module>])— builds the harness with every port faked, applies each module's sqlite migrations to a fresh in-memory database, assembles the router. Exposes{ router, mailer, captcha, rate_limiter, db, clock, kv, http, defer, signer, events, modules, dialect }.- Parity (issue #20):
TestHarness::with_database(modules, Dialect::Sqlite | Dialect::Postgres { url })runs the same harness on a throwaway Postgres 16 database (per-harness, dropped on drop; needs the crate'spostgresfeature and a server atFZ_TEST_POSTGRES_URL).TestHarness::all_dialects(make_modules)/all_dialects_with_ports(make_modules, patch)build one kit per dialect available in the environment so a module suite loops over them — one test definition, every engine. The module factory runs once per dialect: modules may carry per-build state, so kits never share instances. - Fakes:
FakeMailer(recordsMessages;SendOk/NotConfigured/Failmodes, switchable mid-test),FakeCaptcha(allow-all or token list),FakeRateLimiter(scriptedDecisions + call count),FixedClock,MemoryKeyValue,FakeHttpClient(scripted responses + captured requests),EmptyDatabase(servicesSELECT 1only),FakeDefer(collects deferred futures;drain().awaitruns them), and aSignerwith the fixed dummyTEST_HARNESS_SECRET. request(&router, method, path, json?) -> TestResponse { status, headers, json() }—tower::ServiceExt::oneshot, no network.conformance(module)— the shared suite, run once per available dialect: mounts + health listing, request under the prefix, migrations apply twice on fresh databases,view_forhides undeclared ports, the two-concurrent-requests request-id test (ADR 0007), and — for modules with awell_knownrouter — that it serves at the root/.well-knownand never under/v1(#46).assert_wasm_safe_deps(env!("CARGO_PKG_NAME"))—cargo treecheck: noworker/wasm-bindgen/tokio/reqwestin the module's normal dependency tree.
The in-memory Database is cratefield-adapter-sqlite; assertions on
kit.db see exactly what the module wrote. On the Postgres leg kit.db
is a pool on the kit's own tokio runtime marshalled per call, so
pollster-driven tests, spawned threads and deferred handlers all reach
it.