Skip to main content

๐Ÿงช Provisioning Strategies for Test Databases

For test runners that spin up isolated PostgreSQL databases per test flow (like noCRUD), provisioning speed has a huge impact on total runtime.

This guide compares three common provisioning methods and recommends the fastest option for day-to-day usage.


๐Ÿงฉ Why It Mattersโ€‹

If your runner executes dozens of flows like this:

for flow in test_flows:
create_db()
run_test(flow)
drop_db()

...then your provisioning strategy directly affects overall speed.


๐Ÿš€ Provisioning Strategies Comparedโ€‹

StrategyOne FlowAll Flows (~50)Notes
โœ… createdb -T template1.3s7.3sFastest โ€“ clones a pre-provisioned DB
๐ŸŸก psql -f schema.sql2.7s13.6sParses and runs DDL each time
๐Ÿ”ด python manage.py migrate5.8s26.5sSlowest โ€“ ORM initialization overhead

createdb -T clones a PostgreSQL database at the file level. It's much faster than executing SQL or Django migrations.

๐Ÿ”ง Setup (One-Time)โ€‹

Create your template database from schema:

createdb template_db
psql template_db < schema.sql

Or from Django migrations:

createdb template_db
python manage.py migrate --database=template_db

๐Ÿงช Test Flow Provisioningโ€‹

Instead of running migrations or applying SQL on every test, use createdb:

createdb -T template_db test_run_xyz

Boom โ€” near-instant database ready to go.

noCRUD - see provision_django_env_direct_via_template_db which calls provision_db_from_template


๐Ÿงน Cleanupโ€‹

dropdb test_run_xyz

noCRUD - I have a psql wrapper drop_dbs_by_pattern.sh


๐Ÿ”„ Keeping the Template Up-To-Dateโ€‹

If your schema changes, youโ€™ll need to refresh the template:

With SQL:โ€‹

dropdb template_db
createdb template_db
psql template_db < schema.sql

With Migrations:โ€‹

dropdb template_db
createdb template_db
python manage.py migrate --database=template_db

noCRUD - check out refresh-schema.sh