Skip to main content
Headgate has two deliberately different test boundaries. Choose the narrowest one that can truthfully exercise the behavior.
The in-memory store is not a pretend SQL server. Its capability mask honestly omits transactions, inspection, and notifications. Use a live helper when behavior depends on a backend’s atomic gate or one of those capabilities.

Isolation contract

Every helper creates a boundary that no sibling test owns:
  • PostgreSQL creates a generated schema, runs production migrations against it, and supplies connection configuration for that schema.
  • MySQL creates and migrates a generated database, then returns ready-to-use options or a DSN.
  • Redis creates a generated key prefix. Cleanup uses SCAN and bounded DEL batches; it never runs KEYS, FLUSHDB, or FLUSHALL.
Generated names contain the process ID and an atomic process-local sequence. A stale SQL namespace makes creation fail instead of silently sharing state.
Use a dedicated test server or account. The PostgreSQL role needs schema creation permission, the MySQL account needs database creation and deletion privileges, and the Redis account needs SCAN and key-level DEL access.

Rust live stores

MysqlTestDatabase::opts() returns mysql_async::Opts for a pool. RedisTestNamespace::client() and prefix() connect directly to RedisStore::new. Rust cleanup consumes the helper, making double cleanup impossible.

Go live stores

The Require* forms register idempotent cleanup through testing.TB.Cleanup. Use Create* when setup errors need custom handling. MySQLTestDatabase.Open returns a database/sql handle. Redis namespaces plug into headgateredis.New through their Client and Prefix values.

Run live helper tests

Tests skip explicitly when their backend variable is absent. Do not load raw schema files from individual tests: helpers intentionally use the production migration libraries so a test database cannot drift from an installed database.