Przejdź do treści
Biblioteka skilli
Programowanie · Nauka i wyjaśnianie

test-data-patterns

/test-data-patterns

Wyjaśnia, jak testy budują dane, np. Test Data Builder, Object Mother i fixtures, i kiedy które podejście pasuje.

Repozytorium
qa-skills ↗
Licencja
MIT
Ostatnia zmiana repozytorium
12.11.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
1
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
20
Przestarzałość

Brak sygnałów. Repozytorium zmienione 12.11.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Wyjaśnia, jak testy budują dane, np. Test Data Builder, Object Mother i fixtures, i kiedy które podejście pasuje.

Oryginalny opis (EN)

Use for any question or task about how tests build their data, including Object Mother vs Test Data Builder, long constructor calls repeated across tests, and shared fixtures that one test changes and ten others break on. Explains Test Data Builder, Factory, Object Mother, fixture composition, snapshots and production-data anonymization, and when each fits, before picking a tool.

Jak działa

  1. Overview
  2. How to use this catalog
  3. Pattern 1 - Test Data Builder
  4. Pattern 2 - Factory (with traits and associations)
  5. Pattern 3 - Object Mother
  6. Pattern 4 - Fixture composition
  7. Pattern 5 - Snapshot / golden-file
  8. Pattern 6 - Production-Data Anonymisation
  9. Pattern-selection guide
  10. Cross-cutting anti-patterns
Sekcje z nagłówków SKILL.md, w oryginale · 301 linii, 2 454 słów
Podgląd SKILL.md
---
name: test-data-patterns
description: "Use for any question or task about how tests build their data, including Object Mother vs Test Data Builder, long constructor calls repeated across tests, and shared fixtures that one test changes and ten others break on. Explains Test Data Builder, Factory, Object Mother, fixture composition, snapshots and production-data anonymization, and when each fits, before picking a tool."
---

# test-data-patterns

## Overview

A catalog of six ways to construct test data. Pick the pattern here,
then configure the tool with `faker-data` or `synthetic-data-toolkit`.

## How to use this catalog

1. **Inventory.** List how the suite builds data today: grep for inline
   object literals, shared `setUp` / `beforeAll` state, factory files,
   snapshot files, and any production dump loaded into test databases.
2. **Pick.** For each entity, choose a pattern from the
   [Pattern-selection guide](#pattern-selection-guide). One construction
   pattern per entity type; Builder over Factory is the only common mix.
3. **Check.** Run the pattern's anti-pattern table against the existing
   code. Stop and fix any production data that is not anonymised before
   anything else (Pattern 6).
4. **Hand off.** Configure the tool with the skill in
   [Hand-off targets](#hand-off-targets), then re-run the suite twice in
   random order (`pytest --random-order` with pytest-random-order, [`jest --randomize`][jcli]) to confirm
   no test depends on another's data.

Do **not** use this skill to:

- Configure a specific tool - that's the per-language skill for that tool.
- Generate negative / boundary / parameterized test data - that's `negative-test-generator`, `boundary-value-generator`, `pairwise-test-case-generator`.
- Author an E2E seed fixture for the whole suite - that's `seed-data-curator`.

## Pattern 1 - Test Data Builder

**Canonical source:** Nat Pryce and Steve Freeman, the Test Data Builder pattern (see References).

**Definition:** A Test Data Builder is a class with chainable methods (`.withName("Alice").withOrgId(42).build()`) that constructs domain objects step-by-step. Every field has a sensible default; the test overrides only the fields it cares about.

**Concrete implementation (TypeScript, runnable):**

```typescript
type User = { role: string; org: { plan: string } };

class UserBuilder {
  private user: User = { role: "standard", org: { plan: "free" } };
  withRole(role: string) { this.user.role = role; return this; }
  withOrg(org: User["org"]) { this.user.org = org; return this; }
  build(): User { return { ...this.user }; }
}
const aUser = () => new UserBuilder();

// Test overrides only the fields it cares about:
const admin = aUser().withRole("admin").build();
```

### When to use Test Data Builder

- Domain objects have 5+ fields and most tests only care about 1-2.
- The team values explicit "what this test cares about" in the test body.
- The language has chainable / fluent API support (most modern languages).

### Anti-patterns

| Anti-pattern | Why it fails |
|---|---|
| Builders with `.set<Field>(value)` for every field (no defaults) | Loses the pattern's benefit; every test specifies every field |
| Builders that mutate the object in place rather than returning a new one | Test cross-coupling: builders shared between tests leak state |
| Builders that perform side effects (`build()` writes to DB) | Mixes two concerns; the test cannot tell whether it's constructing or persisting |
| Builders for objects with 2 fields | Overhead exceeds benefit; use a struct literal |

## Pattern 2 - Factory (with traits and associations)

**Canonical source:** Thoughtbot's `factory_bot` (Ruby) is the cross-language reference implementation; the pattern adapts the Gang of Four Factory Method for test data.

**Definition:** A Factory is a registered, named template for creating an object. Traits are named modifiers (`:admin`, `:disabled`, `:premium`) that compose with the base template. Associations express relationships (`user.org`, `org.plan`).

**Example (Ruby FactoryBot, the reference implementation):**

```ruby
factory :user do
  name { Faker::Name.name }
  email { Faker::Internet.email }

  trait :admin do
    role { :admin }
  end

  trait :with_org do
    association :org, factory: :org
  end
end

# Test usage:
admin_user = create(:user, :admin, :with_org)
```

**The same factory in Python** ([factory_boy reference][fb]): traits live
in `class Params` and switch on with one boolean; `SubFactory` builds the
association with the caller's strategy, so `build()` saves nothing.

```python
import factory

class UserFactory(factory.Factory):
    class Meta:
        model = User

    name = factory.Faker("name")
    email = factory.Faker("email")
    role = "standard"
    org = None

    class Params:
        admin = factory.Trait(role="admin")
        with_org = factory.Trait(org=factory.SubFactory(OrgFactory))

admin_user = UserFactory.build(admin=True, with_org=True)  # not persisted
```

**Cross-language equivalents** (canonical per-language tool; URLs in References):
- Ruby: `factory_bot` - the origin.
- Python: `factory_boy` - direct port.
- JS/TS: `fishery`, `@faker-js/faker` (lower-level).
- .NET: `Bogus` - Faker-style with factory affordances.
- Java: `data-faker` + handwritten factory or test-data-builder-style libraries.

### When to use Factory

- The project uses a database (factories handle FK relationships via associations).
- The team is on Ruby / Python / JS-TS where mature factory libraries exist.
- Domain objects have many variants (admin / disabled / premium / legacy) - traits express each.

### Anti-patterns

| Anti-pattern | Why it fails |
|---|---|
| Factory definitions that hard-code IDs (`id: 1`) | Tests collide in parallel; factories must let the DB / Faker assign |
| Traits that overlap silently (`:admin` and `:premium` both set `role`) | Order-dependent behaviour; trait composition becomes unpredictable |
| Factories that persist by default (`create` is the only mode) | Slow tests, unnecessary DB writes. Use the `build` strategy unless the test reads from the DB (`synthetic-data-toolkit`, FactoryBot reference) |
| One mega-factory for the entire domain | Becomes a god-object; every test pulls a fully-populated graph |

## Pattern 3 - Object Mother

**Canonical source:** Martin Fowler, Object Mother (see References). Predates Test Data Builder; superseded by it for most use cases but still useful for stable canonical objects.

**Definition:** A central class (the "Mother") exposes named methods that return fully-constructed canonical test objects: `ObjectMother.standardUser()`, `ObjectMother.adminUser()`, `ObjectMother.userInOrgWithFiveMembers()`.

**Fowler's framing:** "An Object Mother is a class that contains methods that create well-known objects for use in tests." Useful when the team has a small, stable set of canonical fixtures.

### When to use Object Mother

- The domain has a small, stable set of canonical objects ("the test admin", "the seed catalogue").
- The team is on a language without first-class factory libraries (older Java, C++, legacy stacks).
- The Test Data Builder pattern is overkill for the small number of cases.

### Anti-patterns

| Anti-pattern | Why it fails |
|---|---|
| Object Mother that grows to 50+ methods | Becomes a god-class; engineers can't find the right factory |
| Methods that return shared mutable instances | Tests cross-couple through the Mother's return values |
| Mixing Mother with Builder (some objects via Mother, some via Builder) | Inconsistent test idiom; vocabulary drift |
| Mother methods with implicit dependencies (`adminUser()` requires `seedOrgs()` to have run) | Implicit ordering creates flakiness |

## Pattern 4 - Fixture composition

**Canonical source:** Gerard Meszaros, *xUnit Test Patterns* - the seminal reference for **Fresh Fixture**, **Shared Fixture**, **Implicit Setup**, **Delegated Setup**, and **Setup Decorator** patterns; it defines the four-phase test pattern (setup / exercise / verify / teardown). See References.

**Definition:** Fixture composition is the pattern of building per-test state from reusable fragments. The three flavours:

| Flavour | When |
|---|---|
| **Fresh Fixture** | Each test creates its own state from scratch. Most isolated; slowest. |
| **Shared Fixture** | Multiple tests share one initialised state. Fastest; brittle to test ordering. |
| **Persistent Fresh Fixture** | Fresh state per test, but persisted in a transaction that rolls back at teardown. The pragmatic middle ground. |

Fowler prefers rebuilding state per test because failures are easier to trace, and switches to clean-up only when rebuilding is too slow ([Eradicating Non-Determinism in Tests](https://martinfowler.com/articles/nonDeterminism.html)).

### When to use Fresh Fixture (default)

- Unit / integration tests with fast setup.
- Tests that mutate state (Shared Fixture would leak across tests).
- Anything parallel-executed.

### When to use Shared Fixture

- E2E tests where setup is genuinely expensive (multi-service stack, large seed data).
- Tests that *only read* the fixture (no mutation).
- The fixture is documented as immutable and the team enforces it.

### Anti-patterns

| Anti-pattern | Why it fails |
|---|---|
| Shared Fixture that some tests quietly mutate | Cross-test coupling; failures depend on test order |
| Fresh Fixture for a 30-minute E2E seed | Test suite time becomes infeasible; team starts skipping tests |
| Multiple fixture flavours in the same suite without explicit convention | Engineers can't tell what to write; bugs creep in |
| Fixture inheritance hierarchies >2 levels deep | Depth-3+ chains break unpredictably |

## Pattern 5 - Snapshot / golden-file

**Canonical source:** Jest snapshot testing is the cross-language reference for the test-code side; Michael Feathers' *Working Effectively with Legacy Code* coined "characterisation tests", the legacy-code-tier version of snapshot testing. See References.

**Definition:** A snapshot test compares the current output of code under test to a previously-saved canonical output ("the golden file"). When the test runs, it serialises the output, compares against the file, fails if they differ. Engineers explicitly approve a new golden file when the change is intentional.

**This skill's role:** Snapshot is a recurring concept in test-data conversation, but the operational details (file naming, sanitisation of timestamps / IDs / PII, per-OS variants, review workflow) are documented in detail by `golden-file-conventions`. Reach for that skill for the operational catalog; this section is the pattern's catalog entry only.

### When to use Snapshot

- Output is structured and large (HTML render, JSON response, CLI output).
- Manual assertions would be tedious or wrong (50 fields to check).
- Changes to output are infrequent and require explicit approval anyway.

### When NOT to use Snapshot

- Output is non-deterministic (timestamps, UUIDs, locale, PII) - sanitise first or skip the snapshot.
- Output changes frequently - the team will rubber-stamp the snapshot update and lose the test's value.
- The behaviour you care about is one field - write an explicit assertion.

## Pattern 6 - Production-Data Anonymisation

**Canonical source:** GDPR Recital 26: pseudonymised data is still personal data, and only truly anonymous information falls outside the regulation ([Recital 26][r26]). `synthetic-pii-generator` is the companion PII-synthesis skill.

**Definition:** Using production data (or production-shaped data) for testing only **after** removing or masking personal data, commercially sensitive data, and any field that would breach privacy or compliance if leaked from a test environment.

### The three anonymisation flavours

| Flavour | Definition | When |
|---|---|---|
| **Masking** | Replace sensitive fields with deterministic placeholders (`X***` for surnames; static fake date) | Production-shape preserved; field-level reversible if needed |
| **Synthesis** | Generate fake data that statistically resembles production (length distributions, locale mix) | No mapping back to production; safest |
| **Tokenisation** | Replace sensitive values with tokens that map back via a secured lookup | Round-tripping to production (rare in QA). This is pseudonymisation: the data is still personal data under GDPR |

### Anti-patterns

| Anti-pattern | Why it fails |
|---|---|
| Copying production DB to staging "for realism", even "internal only" | Test environments have weaker access control; raw personal data leaks from there |
| Treating masked or tokenised data as anonymous | Reversible or linkable data is still personal data (Recital 26) |
| Anonymisation that preserves the join keys | Sensitive relations (who bought what) survive the anonymisation |
| Anonymisation in CI that doesn't anonymise in dev local | Engineers have raw prod data on their laptops |
| Anonymisation as a one-time operation | Production data changes; anonymisation must run continuously |

## Pattern-selection guide

| Need | Pattern | When to mix |
|---|---|---|
| Few-fields, default-most strategy | Test Data Builder | Use Factory underneath the Builder for DB persistence |
| Many variants of one entity | Factory with traits | Combine with Builder for the test-API surface |
| Small stable set of canonical objects | Object Mother | Generally legacy; consider migrating to Builder + Factory |
| Per-test independence | Fresh Fixture | Always the default; reach for Shared only when measured slow |
| Read-only shared state | Shared Fixture | Document immutability; one mutation kills the contract |
| Large structured output | Snapshot / golden-file | See `golden-file-conventions` for operational details |
| Production-shaped privacy-safe data | Anonymisation | Always for production-sourced data; pair with `synthetic-pii-generator` |

## Cross-cutting anti-patterns

| Anti-pattern | Why it fails |
|---|---|
| Mixing all six patterns in one codebase | Engineers can't tell what to write; vocabulary fragments |
| Test data inline-literaled in tests (`{ name: "Alice", id: 1 }`) at scale | Refactors break 200 tests when one schema field changes |
| Test data setup that takes >5s per test | Suite time becomes infeasible; teams skip tests |
| Data construction and persistence collapsed into one method (`createUser()` always writes to DB) | Cannot test the construction logic without the DB |
| Implicit Setup (relies on global state from a previous test) | Tests become order-dependent; flake follows |
| Test data with PII / production keys | Compliance + security breach surface |

## Hand-off targets

- **Configure a specific per-language tool** → `faker-data` (Python / JS / Ruby) or `synthetic-data-toolkit` (FactoryBot / mimesis / Bogus).
- **Build an E2E seed dataset** → `seed-data-curator`.
- **Generate PII (anonymised) test data** → `synthetic-pii-generator`.
- **Snapshot / golden-file operational details** → `golden-file-conventions`.
- **Generate negative / boundary / malicious test data** → `negative-test-generator`, `boundary-value-generator`, `malicious-payload-bank`.
- **Cross-test isolation / fixture scope rules** → `test-isolation-patterns` (sister catalog, in the qa-test-review plugin).
- **Object-model architecture patterns** → `object-model-patterns` (sister catalog).

## References

- Nat Pryce - *Test Data Builders* (the canonical reference for the Builder pattern as applied to test data): http://www.natpryce.com/articles/000714.html
- Nat Pryce and Steve Freeman - *Growing Object-Oriented Software, Guided by Tests* (2009, ISBN 978-0321503626), chapter 22 "Constructing Complex Test Data": https://www.informit.com/store/growing-object-oriented-software-guided-by-tests-9780321503626
- Martin Fowler - *Object Mother* (canonical reference for the Object Mother pattern): https://martinfowler.com/bliki/ObjectMother.html
- Martin Fowler - *Eradicating Non-Determinism in Tests* (Fresh Fixture vs Shared Fixture trade-off, the load-bearing quote on test isolation): https://martinfowler.com/articles/nonDeterminism.html
- Gerard Meszaros - *xUnit Test Patterns: Refactoring Test Code* (2007) (the seminal reference for fixture patterns; cite by book ISBN 978-0131495050).
- thoughtbot - `factory_bot` (Ruby; the canonical Factory implementation): https://github.com/thoughtbot/factory_bot
- FactoryBoy team - `factory_boy` (Python equivalent): https://github.com/FactoryBoy/factory_boy ; reference docs for `Trait`, `SubFactory`, `Faker`, `build` / `create`: [factory_boy reference][fb]
- thoughtbot - `fishery` (TypeScript Factory): https://github.com/thoughtbot/fishery
- bchavez - `Bogus` (.NET; Faker-style with factory affordances): https://github.com/bchavez/Bogus
- Jest CLI - `--randomize`: [jestjs.io/docs/cli][jcli]
- pytest-random-order - `--random-order`: https://github.com/jbasko/pytest-random-order
- Jest - Snapshot Testing (the cross-language reference for the snapshot pattern): https://jestjs.io/docs/snapshot-testing
- Michael Feathers - *Working Effectively with Legacy Code* (the characterisation-tests progenitor of golden-file testing): ISBN 978-0131177055.
- Wikipedia - *Test fixture* (Meszaros's four-phase test pattern): https://en.wikipedia.org/wiki/Test_fixture
- ISTQB glossary - test data: https://glossary.istqb.org/en_US/term/test-data
- ISTQB glossary - fixture: https://glossary.istqb.org/en_US/term/test-fixture
- GDPR Recital 26 - pseudonymised vs anonymous data: [gdpr-info.eu][r26]
- Anonymisation / synthetic-data tooling: Tonic.ai (https://www.tonic.ai/), Gretel.ai (https://gretel.ai/), K2view (https://www.k2view.com/).
- `faker-data`, `synthetic-data-toolkit`, `synthetic-pii-generator`, `golden-file-conventions`, `seed-data-curator` - the per-tool and operational siblings.
- `object-model-patterns`, `test-isolation-patterns` - sister architecture-tier pattern catalogs (step design is `test-code-conventions` §11).

[fb]: https://factoryboy.readthedocs.io/en/stable/reference.html
[r26]: https://gdpr-info.eu/recitals/no-26/
[jcli]: https://jestjs.io/docs/cli

Wersje

RepozytoriumWynikLicencja
Ta strona · testland/qa-skills100MIT
testland/qa100MIT

Migawka bazy z 13.11.2026 · wersja paczki 1fd9158aab8e (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100test-patterns
    Stosuje sprawdzone wzorce testowe: Arrange-Act-Assert, Given-When-Then, Test Data Builders, Object Mother, testy parametryzowane, fixtures, spies i test doubles, by testy były czytelne i niezawodne.
  • 100test-data-builder
    Prawdopodobnie pomaga budować dane testowe wzorcem Test Data Builder w automatyzacji testów.
  • 100test-fixtures-and-factories
    Przygotowuje czytelne i izolowane dane testowe: fixtures, fabryki, buildery, dane seed, katalogi tymczasowe i testowe bazy, także gdy testy dzielą stan.
  • 100test-data-management
    Tworzy dane testowe fabrykami i fixtures, anonimizuje je i generuje dane syntetyczne z Fishery, FactoryBot i Factory Boy, a także zasila i czyści bazy zgodnie z GDPR.
  • 100test-data-builder-generator
    Generuje buildery danych testowych i object mothers w C#, dzięki czemu testy tworzą poprawne obiekty bez powtarzalnego, kruchego setupu.
  • 100test-data-builder
    Buduje realistyczne fixtures, fabryki i zestawy skrajnych danych wzorcem buildera, tak by każdy test miał własne dane, także gdy testy są niestabilne tylko w CI.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.