Skip to main content

Test fixtures

Known, pre-loaded data a test runs against, so its assertions can rely on a predictable starting state instead of whatever happens to be in the database.

A test that asserts against an empty, unpredictable, or previously-mutated database is really testing whatever state happens to be left over from the last run, not the behavior it claims to test. Fixtures fix that: a known set of rows, loaded fresh before the test runs, so "this room is already booked on this date" is a fact the test controls instead of one it hopes is true.

The loader itself is usually the least interesting code in the whole test suite, and that's by design. It reads a .sql file, or runs a couple of insert statements, before each test. What matters isn't the mechanism, it's the discipline: fixtures get reset before every run, so test order never matters and a failure always points at real behavior, not leftover state from whichever test happened to run before it.

Skimping on this is a common false economy: a test suite that shares one mutable database across tests looks faster to build, right up until a failure takes an hour to explain because it depends on which other test happened to run first.

Appears in