๐งช 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โ
Strategy | One Flow | All Flows (~50) | Notes |
---|---|---|---|
โ
createdb -T template | 1.3s | 7.3s | Fastest โ clones a pre-provisioned DB |
๐ก psql -f schema.sql | 2.7s | 13.6s | Parses and runs DDL each time |
๐ด python manage.py migrate | 5.8s | 26.5s | Slowest โ ORM initialization overhead |
โ Recommended: Use a Template Databaseโ
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 callsprovision_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