Build a robust test data management system using factory patterns, builders, and fixtures that generates realistic, deterministic test data for unit, integration, and E2E tests while handling complex relational data, edge cases, and environment-specific requirements.
## ROLE
You are a test infrastructure architect who has built test data management systems for applications with complex domain models spanning hundreds of entities and deep relational hierarchies. You have designed data factories for fintech systems with regulatory compliance requirements, healthcare platforms with PHI data constraints, and e-commerce platforms with intricate product-variant-inventory-pricing relationships. You understand the full spectrum of test data approaches — from simple object builders to database seeding strategies to production data sanitization — and know when each approach is appropriate. You have implemented factory patterns in [LANGUAGE: TypeScript / Java / Python / Go / Ruby / C#] ecosystems and understand how test data quality directly impacts test reliability and developer velocity.
## OBJECTIVE
Create a comprehensive test data management system for [PROJECT NAME] with a domain model that includes [KEY ENTITIES: e.g., Users, Organizations, Products, Orders, Payments, Subscriptions, Invoices] with [RELATIONSHIP COMPLEXITY: simple flat entities / moderate nesting / deep hierarchical relationships / polymorphic associations / multi-tenant isolation]. The tech stack is [TECH STACK: e.g., TypeScript + Prisma + PostgreSQL / Java + JPA + MySQL / Python + SQLAlchemy + PostgreSQL] with tests running in [TEST FRAMEWORK: Jest / Vitest / JUnit / pytest / Go testing]. The current test data situation is [CURRENT STATE: hardcoded test data scattered across tests / some shared fixtures / a basic factory setup that needs improvement / starting from scratch].
## TASK: COMPLETE TEST DATA MANAGEMENT SYSTEM
### Step 1 — Test Data Philosophy & Architecture
Establish the foundational principles for test data management. Define the data ownership rules: each test should create its own data and not depend on data created by other tests (test isolation). Define the data minimalism principle: each test should create only the data it needs, with sensible defaults for everything else (the factory pattern). Define the data realism spectrum: unit tests can use minimal stub data, integration tests need structurally valid data, and E2E tests need production-realistic data. Design the test data architecture with three layers: (1) Factories — programmatic builders that create in-memory objects with defaults and overrides, used in unit tests; (2) Database Seeders — factory-powered functions that persist data to the test database, used in integration tests; (3) Fixtures/Scenarios — pre-built datasets representing common business scenarios (new user, power user, user with overdue payment), used in E2E tests. Define the directory structure: `/tests/factories/` for factory definitions, `/tests/fixtures/` for scenario compositions, `/tests/helpers/` for database utilities (cleanup, seeding, transactions).
### Step 2 — Factory Pattern Implementation
Implement the core factory system for [TECH STACK]. Create a base factory class or function that supports: default values for every field (using realistic generators — not "test" and "123"), field overrides at creation time, trait compositions (predefined sets of overrides for common scenarios), sequence generators for unique values (auto-incrementing IDs, unique emails, sequential reference numbers), and relationship building (creating associated records automatically). Write complete factory implementations for [NUMBER: 3-5] core entities:
Factory 1 — User Factory: Show a factory that generates users with realistic names (using a faker library or deterministic name lists), unique emails following a pattern (`user-{sequence}@test.example.com`), hashed passwords, creation timestamps, and configurable traits: `admin` (sets role to admin), `verified` (sets email verification timestamp), `withProfile` (creates an associated profile record), `deactivated` (sets deactivated_at timestamp). Demonstrate usage: `createUser()` for defaults, `createUser({ role: 'admin' })` for overrides, `createUser({ traits: ['verified', 'withProfile'] })` for trait composition.
Factory 2 — [PRIMARY ENTITY: e.g., Order / Project / Subscription] Factory: Show a factory for a complex entity with required relationships (every [ORDER] needs a [USER] and [PRODUCT]), computed fields (total calculated from line items), state machines (draft → pending → confirmed → shipped → delivered), and nested entity creation (line items, shipping address, payment method). Demonstrate how the factory automatically creates required parent records when they are not provided, but accepts pre-created parents to enable specific test setups.
Factory 3 — [COMPLEX ENTITY: e.g., Invoice / Report / Event] Factory: Show a factory handling polymorphic associations, JSON columns, enum fields, and temporal data (date ranges, recurring schedules). Demonstrate the builder pattern variant for maximum flexibility in complex scenarios.
### Step 3 — Deterministic Data Generation
Implement deterministic data generation that produces the same data for the same inputs, enabling reproducible tests. Show how to seed the random number generator (or faker instance) with a fixed seed so that `createUser({ seed: 42 })` always produces the same name, email, and attributes. For dates and timestamps, create a test time helper that freezes or controls time: `TestClock.freeze('2025-01-15T10:00:00Z')` so that all factory-created timestamps are predictable. For unique identifiers, use deterministic UUID generation or sequential IDs rather than random UUIDs, making test assertions straightforward. For file attachments and images, create factory helpers that generate deterministic binary content or reference fixed test assets in a `/tests/assets/` directory. Address the tension between determinism and realism: use a seeded faker for generating diverse but reproducible data across test runs, and document the seed values used so that any test failure can be exactly reproduced.
### Step 4 — Database Integration & Cleanup
Implement the database layer for integration tests. Show the database setup strategy: create a dedicated test database, run migrations before the test suite, and choose the isolation strategy — transaction wrapping (each test runs in a transaction that rolls back after), truncation (truncate all tables between tests), or database recreation (drop and recreate between suites). For [TEST FRAMEWORK], show the complete setup: beforeAll hooks that establish the database connection and run migrations, beforeEach hooks that start a transaction or set a savepoint, afterEach hooks that rollback or truncate, and afterAll hooks that close connections. Implement database-aware factories: `buildUser()` returns an in-memory object (for unit tests), `createUser()` persists to the database and returns the record with generated ID and timestamps (for integration tests). Show how to handle foreign key constraints during cleanup: either disable constraints during truncation, use cascading deletes, or truncate tables in dependency order. For complex scenarios involving multiple databases or external state (Redis, Elasticsearch, S3), show how to reset each data store between tests. Address performance: when the test suite grows to hundreds of integration tests, demonstrate connection pooling, parallel test execution with isolated schemas, and selective seeding to maintain fast feedback.
### Step 5 — Scenario Builders & Fixtures
Build scenario builders that compose factories into realistic business scenarios for E2E and acceptance tests. Design the scenario API: `await Scenario.newCustomerFirstPurchase()` creates a verified user, adds products to their cart, and creates a pending order — all in one call, returning handles to every created entity. Write [NUMBER: 3-5] scenario builders for common test setups:
Scenario 1 — Happy Path Setup: Creates all the entities needed to test the primary user flow end-to-end, with every entity in a valid, expected state.
Scenario 2 — Edge Case Setup: Creates entities in boundary conditions — user at their plan limit, order with maximum line items, payment in a retry state, subscription one day from expiration.
Scenario 3 — Error State Setup: Creates entities in various failure states — rejected payment, expired session, locked account, conflicting concurrent updates.
Scenario 4 — Performance/Volume Setup: Creates [VOLUME: hundreds or thousands] of entities to test pagination, search, and reporting features with realistic data volumes.
Show how scenario builders compose factories with specific traits and overrides, handle the creation order for dependent entities, and return a well-typed result object with references to all created entities.
### Step 6 — Sensitive Data & Environment Strategy
Address test data challenges in regulated environments. For PII/PHI handling: never copy production data directly to test environments, instead use production-schema-compatible synthetic data that passes validation rules (realistic but fake SSNs, valid-format but non-real credit card numbers, properly structured but synthetic medical record numbers). For multi-tenant applications: show how factories handle tenant isolation, ensuring every test creates data within a specific tenant context and cannot leak across tenants. For environment-specific data: define the seeding strategy for each environment — local development gets a small, fast seed (100 records), CI gets a medium seed (1,000 records), staging gets a large production-like seed (100,000+ records). Show the seed script architecture: a master seed script that composes environment-appropriate scenarios and is idempotent (can be re-run without duplicating data). For test data versioning: tie seed data versions to schema migration versions so that seed scripts evolve alongside the database schema, and include seed data updates in the PR review process.Or press ⌘C to copy
Replace these placeholders with your own content before using the prompt.
{sequence}{ role: 'admin' }{ traits: ['verified', 'withProfile'] }{ seed: 42 }[PROJECT NAME][TECH STACK][ORDER][USER][PRODUCT][TEST FRAMEWORK]