The problem with test data#

Every project that touches a database eventually needs data to test against. It sounds like a small task. It is not, and the reasons it is not are worth understanding before evaluating any tool that claims to solve it, this one included.

Three approaches, three different failures#

Writing fixtures by hand#

This is where most projects start, and it works until the schema moves. Someone adds a not-null column and every fixture in the suite breaks at once. Someone renames a table and the failures are worse, because now they are silent until runtime.

Hand-written fixtures also share a quieter defect: they are invariably too tidy. Three customers, two orders, no nulls, no unicode, no apostrophe in a surname, no fifty-thousand-row table that makes a query plan collapse. The suite passes because the data was chosen, consciously or not, to make it pass. Then production supplies data nobody chose.

Copying production data#

This solves realism instantly, which is exactly why it is tempting, and it substitutes a far worse problem. Real customer records on a developer laptop, in a CI log, or in a staging database that was never hardened is a privacy incident waiting for its trigger. Under the GDPR it is a reportable one.

The usual answer is to anonymise the copy first. That is harder than it sounds. Removing names and email addresses does not remove identifiability: re-identification of individuals from datasets stripped of direct identifiers is a well-documented result, not a hypothetical risk, because combinations of ordinary attributes are far more unique than intuition suggests. Anonymisation done properly is a research problem, not a checkbox in a migration script.

Generating rows at random#

The moment data becomes relational, randomness stops being enough. A database enforces referential integrity, so a row in orders naming a customer who does not exist is not merely unrealistic, it is rejected outright by the engine.

That constraint has structure. Foreign keys define a directed graph over the tables, and valid insertion order is a topological ordering of that graph. Deriving it is mechanical, which is precisely the argument for not doing it by hand: it is exactly the kind of bookkeeping that a person gets wrong on a schema of any size, and that a machine gets right every time.

The cost they share#

All three approaches carry the same hidden expense. Test data is not written once. A schema is a living thing, and whichever approach a team picks has to be maintained against it indefinitely, by hand, usually by whoever least wants the job. The initial effort is visible and gets budgeted. The maintenance is neither.

Continue with The approach taken for how this tool answers the problem, or Scope and boundaries for where it stops.