← All skills

Fixture Diet

Cuts test setup down to the few facts the test actually depends on, so the test says what it means.

testingreadabilityrefactoringmaintenanceminutes

When to reach for it

When a test file opens with thirty lines of setup, or when adding one field to a model breaks a dozen tests that were never about that field.

What changes

  • Each test shows the values its assertion depends on, in the test body, named for the role they play — everything else moves behind a builder with defaults.
  • You can read a test top to bottom and point at the input that causes the outcome without opening a shared fixture file.
  • Adding a required field to a model touches one builder instead of every test that happens to construct that model.
  • Shared mutable fixtures are replaced by per-test construction, removing a whole class of order-dependent failures.
  • Setup lines drop by a number you can count, and a deliberate break in the behaviour still turns the slimmed tests red.

Pairs with

SKILL.mdpaste into your agent

Fixture Diet

Setup is not free. Every line of it is something the reader has to hold in their head while deciding whether the test proves anything at all.

1. Find what is load-bearing

Take one test. Delete setup lines until it fails, and look at what the failure demanded. That is the real input. Everything you removed without consequence was decoration.

2. Rebuild the test around the values it asserts on

Values the assertion depends on belong in the test body, visible, named for their role in the story:

  • const expiredAt = daysAgo(1) in the test
  • const cart = buildCart({ items: [] }) in the test
  • Everything else behind a default nobody has to read

3. Move the remainder behind a builder

One function per entity that returns a valid object and accepts overrides. Tests then read as "a subscriber, except their trial ended yesterday", which is the sentence you would have said out loud anyway.

4. Stop sharing mutable state

Build fresh objects inside each test. A shared fixture that any test can mutate is an ordering dependency waiting to be discovered on a Friday afternoon by somebody else.

5. Delete what nothing uses now

Remove the fixture files, factory helpers and seed data no test references any more. Search for the names before deleting, then delete without ceremony.

6. Check you did not soften the suite

Break the behaviour on purpose and confirm the slimmed tests still go red. Shorter tests that no longer detect anything are a regression dressed as a cleanup.

Rules

  • Do not hide a value the test asserts on inside a builder default. If the test is about an adult account, the age belongs in the test.
  • Do not build a fixture framework larger than the code it sets up.
  • Do not swap real setup for a mock purely to shorten it. A builder keeps what the test proves; a mock changes it.
  • Do not seed an entire database for a test that reads one row.
  • Do not keep a fixture because something might need it later. It can come back in one line when something does.