Run tests on a throwaway database, never the real one
A test suite truncated 4,212 real users. This gives tests their own database plus a guard that refuses to run on any other.
The fix
Make a separate database only for tests and point only the tests at it. Dropping it first means every run starts clean. npm run migrate stands for whatever applies your schema. Shell syntax here is bash or zsh.
dropdb --if-exists app_test
createdb app_test
DATABASE_URL=postgres://localhost/app_test npm run migrate
DATABASE_URL=postgres://localhost/app_test npm testAdd a guard that refuses anything else
A line in CLAUDE.md or a prompt is advice. Code is not. This script stops the run unless the database name ends in _test. It also stops when DATABASE_URL is missing, because new URL() throws on an invalid URL. Import it first in your test setup file.
// test/guard.js
const url = new URL(process.env.DATABASE_URL);
const name = url.pathname.slice(1);
if (!name.endsWith("_test")) {
throw new Error(`Refusing to run tests on "${name}"`);
}Check it worked
The guard never connects to a database, so it is safe to try on its own. The first run must fail, the second must stay silent.
DATABASE_URL=postgres://localhost/app node test/guard.js
# Error: Refusing to run tests on "app"
DATABASE_URL=postgres://localhost/app_test node test/guard.js
# no output: allowedPro tip: clone the database from a template
Migrate once into a template, then create each run's database as a copy. createdb -T is the shell form of CREATE DATABASE ... TEMPLATE. PostgreSQL needs the template to have no other open connections while it is copied.
createdb app_template
DATABASE_URL=postgres://localhost/app_template npm run migrate
dropdb --if-exists app_test
createdb -T app_template app_testPro tip: a Postgres that vanishes after the run
With --rm the container is removed when it stops. -p 5433:5432 maps host port 5433 to the container's 5432, so it will not clash with a local Postgres. Wait for the database to finish starting before the tests.
docker run --rm -d --name pgtest -p 5433:5432 \
-e POSTGRES_PASSWORD=test -e POSTGRES_DB=app_test postgres
# wait until it accepts connections, then:
DATABASE_URL=postgres://postgres:test@localhost:5433/app_test \
npm test
docker container stop pgtestCommon mistake
Trusting a .env.test file. With Node's --env-file, a variable already set in your shell beats the file. If DATABASE_URL is exported in your terminal from yesterday's work, the tests quietly use it. The guard catches this; a file alone does not.
Official docs
- www.postgresql.org/docs/current/app-createdb.html
- www.postgresql.org/docs/current/app-dropdb.html
- www.postgresql.org/docs/current/manage-ag-templatedbs.html
- nodejs.org/api/url.html
- nodejs.org/api/cli.html
- hub.docker.com/_/postgres
- docs.docker.com/reference/cli/docker/container/run
- docs.docker.com/reference/cli/docker/container/stop
- code.claude.com/docs/en/best-practices
- code.claude.com/docs/en/memory
One fix of twenty: the whole Claude Code survival kit.
Follow @whyshouldaicareA new disaster and its fix every day. Comment the word under a reel to get its guide.