Fixture Isolation
Fixture isolation guarantees each test starts from controlled state — setup creates, teardown restores — preventing order dependence and cross-test contamination that manifests as flakes.
Definition
Fixture isolation is the discipline that tests share no mutable state: each test constructs what it needs and cleans up or rolls back afterward. Database fixtures use transactions rolled back per test or per-test schemas; filesystem fixtures use temp directories; in-memory state resets per case. Violations surface as order dependence and environment-dependent failures.
Context and scope
Implemented via test framework fixtures (pytest, Jest beforeEach), transactional rollback wrappers, and ephemeral containers or testcontainers. The backbone of hermetic suites.
Common misconceptions
- Tests in one suite share a database anyway — shared state is exactly why reordering the suite changes outcomes
- Truncate-after-each is as good as rollback — truncation is slower and breaks foreign key ordering; rollback is atomic and order-free
- Parallelization requires buying more hardware — isolation is what makes parallelization safe at all; without it, runners serialize
Anti-patterns
- Seeding a global database once for speed and growing an invisible dependency graph between tests
- Ordering tests alphabetically as a fix and shipping a suite that only passes in that order
- Cleaning up with best-effort deletes that miss rows added by assertions under failure
Related concepts
Related examples
Authoritative source
What it is
Two tests touching the same rows produce a coupling: whichever runs first changes what the second sees. Isolation cuts the coupling — every test sees a fresh, known world.
How it works
Transaction-per-test wraps each case in a transaction rolled back on completion — atomic, ordering-agnostic, fast. Alternative: per-test schemas or databases created from template snapshots. Filesystem and clock state isolate through temp dirs and fake timers. The framework fixture graph decides scope — function, module, session — and session scope must contain only read-only data.
When to enforce
Before parallelizing a suite, before adding retries, and whenever flakes correlate with test shuffling. CI should run randomized orders periodically to detect emergent couplings.
Pitfalls
Session-scoped mutable fixtures quietly reintroduce coupling under the guise of performance. Rollback misses side effects outside the transaction — message queue publishes, cache writes, files. Tests asserting on each other data create the coupling in the assertions themselves.