--- slug: fixture type: pattern summary: "The known starting state a test runs against, giving each test a clean, predictable foundation so failures point at the code, not the environment." created: 2026-04-04 updated: 2026-05-22 related: harness: relation: managed-by note: "The harness handles fixture lifecycle." observability: relation: contrasts-with note: "Fixtures control inputs for testing, while observability captures outputs in production." test: relation: used-by note: "Tests consume fixtures." test-oracle: relation: refines note: "Fixtures provide the controlled inputs that make oracle comparisons deterministic." --- # Fixture > **Pattern** > > A named solution to a recurring problem. *Also known as: Test Fixture, Test Data* ## Context A [Test](test.md) needs to run in a known state. The function under test might need a database with specific records, a file system with specific files, or an object configured in a specific way. The fixture is that known starting point. This is a **tactical** pattern that works closely with the [Harness](harness.md) to make tests reliable and repeatable. ## Problem Tests that depend on external state are fragile. If a test expects a specific user to exist in the database and someone deletes that user, the test fails for reasons unrelated to the code it's checking. If two tests share state and one modifies it, the other may pass or fail depending on execution order. How do you give each test a clean, predictable starting point? ## Forces - Tests need data and environment to run against. - Shared state between tests creates hidden dependencies and flaky results. - Setting up realistic state can be slow and complex. - Overly simplified fixtures may miss real-world bugs. - Fixture code must be maintained alongside the code it tests. ## Solution Create a fixed, controlled setup for each test or group of tests. A fixture provides the data, objects, configuration, and environment that the test needs, and nothing more. After the test runs, the fixture is torn down so the next test starts fresh. Fixtures can be as simple as a few variables or as complex as a populated database. Common approaches: **Inline fixtures** declare their data directly in the test. This is the clearest approach for simple tests; you can see everything the test needs by reading the test itself. **Shared fixtures** are set up once and reused across multiple tests. This saves time but introduces the risk of one test contaminating another. Most harnesses offer "setup before each test" and "setup once before all tests" hooks to manage this tradeoff. **Factory fixtures** use helper functions or libraries to generate test data with sensible defaults. Instead of specifying every field of a user record, you call `make_user(name="Alice")` and the factory fills in the rest. This keeps tests focused on what matters. **External fixtures** load data from files (JSON snapshots, SQL dumps, recorded API responses). These are useful for complex data structures but can become stale if the data format changes. ## How It Plays Out An e-commerce test suite needs order data. Each test that involves orders uses a factory: `create_order(items=3, status="shipped")`. The factory generates a complete order with realistic but deterministic data. Tests are readable (you see the relevant setup at a glance) and isolated, because each test creates its own order. In an agentic workflow, fixtures serve a dual purpose. They provide the test data that lets an AI agent verify its work, and they document the expected shape of the system's data. When an agent sees a fixture that creates a user with an email, a name, and a role, it learns the structure of a user without reading the schema. Well-named fixtures become a form of living documentation. > **⚠️ Warning** > > Beware of fixture bloat. If setting up a test requires 50 lines of fixture code, the test is probably testing too many things at once, or the code under test has too many dependencies. Fixture pain is a design signal. > **💡 Example Prompt** > > "Create a test factory for Order objects. It should accept optional overrides for status, item count, and customer ID, and fill in sensible defaults for everything else. Use it in all the order-related tests." ## Consequences Good fixtures make tests fast, reliable, and readable. Each test starts from a known state, runs its checks, and cleans up. Failures point to real bugs, not to stale data or test ordering issues. The cost is maintenance. Fixtures are code, and they must evolve alongside the system. When a data model changes (a new required field, a renamed column) every fixture that touches that model must be updated. Factory-based fixtures reduce this cost by centralizing the construction logic in one place. ## Sources - Kent Beck's *[Simple Smalltalk Testing](https://www.cambridge.org/core/books/kent-becks-guide-to-better-smalltalk/simple-smalltalk-testing/0D2F14E0129D5EF29E85D796A5B845FC)* (1994, collected in *Kent Beck's Guide to Better Smalltalk*) introduced the SUnit testing style that shaped the xUnit family: test cases run against a predictable setup, then clean up afterward. - Gerard Meszaros formalized fixture setup as a pattern language in *[A Pattern Language for Setting up XUnit Test Fixtures](https://hillside.net/plop/2004/papers/gmeszaros0/PLoP2004_gmeszaros0_0.htm)* (PLoP 2004) and expanded the taxonomy in *[xUnit Test Patterns](https://www.oreilly.com/library/view/xunit-test-patterns/9780131495050/ch20.html)* (2007). - Martin Fowler's *[Object Mother](https://martinfowler.com/bliki/ObjectMother.html)* (2006) names one factory-style approach to reusable standard fixtures and explains why these canned objects help teams share test examples while creating coupling costs. - Steve Freeman and Nat Pryce's *[Growing Object-Oriented Software, Guided by Tests](https://growing-object-oriented-software.com/)* (2009) treats complex test data as a practical test-driven-development problem, which underlies the article's advice to use factories and builders when inline fixtures become noisy. --- - [Next: Test-Driven Development](test-driven-development.md) - [Previous: Harness](harness.md)