How do you keep integration tests isolated when they share a database?
Quick Answer
Options: wrap each test in a transaction and roll it back; use a library like Respawn to delete all data between tests; or spin up a fresh database per test class (Testcontainers). Each test seeds exactly the data it needs. Disable parallelism, or give each parallel worker its own database.
The three approaches are: wrap each test in a transaction and never commit, which is fast but falls apart if the code opens its own transaction; use Respawn, which wipes all the rows in a foreign-key-safe order between tests so you start clean each time; or run a fresh database container per test class with Testcontainers for total isolation at the cost of startup time. Whichever I pick, each test is responsible for seeding its own data and never assumes anything is left over from another test.
- Transaction rollback — fast, but breaks if the code under test manages its own transactions or if you need to test across connections.
- Respawn — after each test, delete rows in FK-safe order; keeps the schema, gives a clean slate.
- Container per class — total isolation, slower startup; good with Testcontainers.
- Never rely on data left by a previous test — that's the flaky-test trap.