- Skill ID
- petrkindlmann/qa-skills/test-data-management
- Publisher
- petrkindlmann
- Repository
- qa-skills
- Installs
- 0
- Files
- 3
- License
- MIT
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
petrkindlmann/qa-skills/test-data-managementInstalls these files- SKILL.md
- references/factories.md
- references/seeding-and-synthetic.md
What this skill tells the agent
<objective> Create, maintain, and clean up test data that is deterministic, isolated, realistic, and safe. Good test data is the foundation of reliable tests -- without it, tests are either flaky (shared mutable state), unrealistic (hardcoded nonsense values), or dangerous (production PII in test environments). This skill delivers factories, fixtures, idempotent seeds, anonymization pipelines, and cleanup strategies that survive parallel execution. </objective>
Quick Route
| Situation | Go to |
|---|---|
| Need fresh entity data with per-test overrides | Factory Patterns → references/factories.md |
| Mocking an API response or golden file | Fixture Strategies → references/factories.md |
| Copying production data anywhere non-prod | Data Anonymization |
| Populating a test DB / reference data idempotently | Database Seeding → references/seeding-and-synthetic.md |
| Cleaning up after tests / parallel isolation | Cleanup Strategies → references/seeding-and-synthetic.md |
| Generating edge cases and boundary values | Synthetic Data → references/seeding-and-synthetic.md |
Discovery Questions
Before designing a test data strategy, understand the current state. Check .agents/qa-project-context.md first -- if it exists, use it as the foundation and skip questions already answered there.
Current Data Practices
- How is test data created today? (manually, scripts, copy of production, none)
- Do tests share data or does each test create its own?
- How is test data cleaned up? (truncate, rollback, manual, never)
- Are there seed scripts? Are they idempotent?
Privacy and Compliance
- Does the product handle PII? (names, emails, addresses, phone numbers, SSNs)
- Are there GDPR, HIPAA, PCI-DSS, or other data protection requirements?
- Is production data ever used in test environments?
Scale and Complexity
- How large are the test datasets? (dozens of records, thousands, millions)
- How complex are the data relationships? (simple CRUD, deep nested hierarchies, polymorphic)
- Are there cross-service data dependencies? (microservices sharing data)
Core Principles
1. Each Test Owns Its Data
Tests that rely on pre-existing shared data are fragile. When Test A modifies shared data, Test B breaks. Every test should create exactly the data it needs, verify against that data, and clean up after itself. This enables parallel execution and eliminates ordering dependencies.
2. Factories Over Fixtures for Dynamic Data
Static fixtures (JSON/YAML files) are appropriate for reference data that does not change (country codes, currency lists). For entity data that tests create and manipulate (users, orders, products), use factory functions that generate fresh instances with sensible defaults and allow per-test overrides.
3. Anonymize Production Data Before Use
Production databases contain the most realistic data, but they also contain real user information. Never copy production data to test environments without anonymization. Replace PII with synthetic equivalents while preserving data distributions and relationships.
4. Deterministic Data Enables Reproducible Tests
Tests should produce the same results regardless of when or where they run. Avoid Math.random(), Date.now(), or auto-increment IDs in assertions. Use seeded random generators (faker.seed(n)), fixed timestamps, factory sequences, and -- when an ID must be a UUID you assert on -- a seeded faker.string.uuid() so it stays stable across runs.
5. Minimize Data, Maximize Signal
Create only the data each test needs. A test for user search does not need a complete user profile with billing address, payment method, and order history. Over-specified test data obscures the intent of the test and increases maintenance burden.
Factory Patterns
Factories are functions that produce test data with sensible defaults, allowing individual tests to override only what matters for their scenario. Fishery (2.4.0) is the default for TypeScript, FactoryBot (6.6.0) for Ruby, factory-boy (3.3.3) for Python; all pair with faker (v10.4.0) for realistic field values.
See references/factories.md for the full Fishery (with associations and deterministic UUIDs), FactoryBot (User + Product out_of_stock/discounted traits), Factory Boy (class Params + Trait), and Playwright fixture implementations. The shape every factory follows:
- Defaults + overrides —
Factory.defineproduces sensible defaults; tests pass overrides for the one field they care about (userFactory.build({ role: 'admin' })). - Sequences for unique fields —
sequence(Fishery),sequence(:email)(FactoryBot),factory.Sequence(Factory Boy) — never hardcode IDs or emails. - Traits for variants — name common states (
:admin,:inactive,out_of_stock,discounted) instead of spawning a fixture file per combination. - Associations — one factory builds another (an order builds its user), keeping referential structure without manual wiring.
When to Use Factories vs Fixtures
| Scenario | Factories | Static Fixtures |
|---|---|---|
| Entity data that tests create/modify | Yes | No |
| Reference data (countries, currencies, configs) | No | Yes |
| Data with many variations per test | Yes | No -- file explosion |
| Data with complex relationships | Yes -- associations | No -- hard to maintain |
| API response mocks | No | Yes -- JSON fixtures |
| Snapshot/golden file comparisons | No | Yes |
Decision rule: If the data has a lifecycle (created, modified, deleted during tests), use a factory. If the data is read-only reference material, use a fixture file.
Fixture Strategies
Three fixture shapes, all in references/factories.md:
- Static fixtures (JSON/YAML) — best for API response mocks (
page.route+route.fulfill), config data, and golden file comparisons. - Dynamic fixtures (Playwright) —
test.extendcreates data via API before the test and deletes it afterawait use(...). The standard per-test setup/teardown. - Fixture composition — combine factory-built data (
userFactory.build(),orderFactory.buildList(3)) inside a singletest.extendthat seeds and cleans up in one step.
Data Anonymization
When production data is needed for realistic testing, anonymize it before use.
PII Masking Rules
| Data Type | Anonymization Method | Example |
|---|---|---|
| Faker email with original domain pattern | jane.doe@acme.com -> user-7291@test.example.com | |
| Full name | Faker name | Jane Doe -> Alice Johnson |
| Phone number | Faker phone, preserve format | +1-555-123-4567 -> +1-555-987-6543 |
| Address | Faker address, preserve country/region | 123 Main St, NYC -> 456 Oak Ave, NYC |
| SSN/National ID | Test pattern | 123-45-6789 -> 000-00-0001 |
| Credit card | Test card numbers | 4111-... -> 4242-4242-4242-4242 |
| Date of birth | Shift by fixed offset | 1990-03-15 -> 1987-07-22 |
The anonymization pipeline -- seeded Faker for determinism, an in-memory lookup table, parent-records-first ordering, and a wrapping transaction -- is in references/seeding-and-synthetic.md (Anonymization with Faker.js, Referential Integrity During Anonymization). Anonymizing a user's email must also update that email everywhere it is referenced (orders, comments, audit logs); process parents first, children second, using the same lookup, all inside one transaction.
GDPR Compliance Checklist
- [ ] No real PII exists in any non-production environment
- [ ] Anonymization is irreversible (no lookup table mapping back to originals is stored)
- [ ] Anonymization preserves data distributions (age ranges, geographic spread) for realistic testing
- [ ] Anonymized data cannot be re-identified through combination of quasi-identifiers
More from petrkindlmann
Use this skill in a project
Open any RiverX project, search the Skills panel for petrkindlmann/qa-skills/test-data-management, and install it in one click.
