Test Data Generator
Overview
Generate realistic, type-safe test data including fixtures, factory functions, seed datasets, and edge case values. Supports Faker.js, Factory Bot patterns, Fishery (TypeScript factories), pytest fixtures, and database seed scripts.
Prerequisites
- Data generation library installed (Faker.js/@faker-js/faker, Fishery, factory-boy for Python, or JavaFaker)
- Database schema or TypeScript/Python type definitions for the data models
- Test framework with fixture support (Jest, pytest, JUnit)
- Seed management for reproducible random data (
faker.seed())
- Database client for seed data insertion (if generating database fixtures)
Instructions
- Read the project's data models, TypeScript interfaces, database schemas, or ORM definitions to understand the shape of all entities.
- For each entity, create a factory function that produces a valid default instance:
- Use Faker methods matched to field semantics (e.g.,
faker.person.fullName() for names, faker.internet.email() for emails).
- Provide sensible defaults for required fields.
- Allow overrides via a partial parameter for test-specific customization.
- Set a deterministic seed for reproducibility (
faker.seed(12345)).
- Generate edge case data variants for each entity:
- Empty values: Empty strings, null, undefined, empty arrays.
- Boundary values: Maximum string length, integer overflow, zero, negative numbers.
- Unicode and i18n: Names with accents, CJK characters, RTL text, emoji.
- Adversarial inputs: SQL injection strings, XSS payloads, excessively long strings.
- Temporal edge cases: Leap years, timezone boundaries, epoch zero, far-future dates.
- Create relationship factories that build connected entity graphs:
- A user factory that also creates associated addresses and orders.
- Configurable depth to avoid infinite recursion.
- Lazy evaluation for optional relationships.
- Generate database seed files for integration tests:
- SQL insert scripts or ORM seed functions.
- Idempotent operations (use
ON CONFLICT or INSERT IF NOT EXISTS).
- Separate seed sets for different test scenarios (empty state, populated state, edge cases).
- Write fixture files in JSON, YAML, or TypeScript for static test data:
- Group fixtures by test scenario.
- Include both valid and invalid data sets.
- Validate generated data against the schema to ensure factories remain in sync with model changes.
Output
- Factory function files (one per entity) in
test/factories/ or tests/factories/
- Edge case data collections covering boundaries and adversarial inputs
- Database seed scripts for integration test environments
- JSON/YAML fixture files for static test data
- Factory index file exporting all factories for easy test imports
Error Handling
| Error |
Cause |
Solution |
| Factory produces invalid data |
Schema changed but factory not updated |
Add a validation step that runs the factory output through the schema validator |
| Duplicate unique values |
Faker generates collisions in small datasets |
Use sequential IDs or append a counter; increase Faker's unique retry limit |
| Database seed fails on foreign key |
Seed insertion order violates referential integrity |
Sort seed operations topologically by dependency; disable FK checks during seeding |
| Factory recursion overflow |
Circular relationships (User -> Order -> User) |
Limit relationship depth; use lazy references; break cycles with ID-only references |
| Non-deterministic test failures |
Random seed not set consistently |
Call faker.seed() in beforeAll or at factory module level; document seed values |
Examples
TypeScript factory with Fishery:
import { Factory } from 'fishery';
import { faker } from '@faker-js/faker';
interface User {
id: string;
name: string;
email: string;
role: 'admin' | 'user';
createdAt: Date;
}
export const userFactory = Factory.define<User>(({ sequence }) => ({
id: `user-${sequence}`,
name: faker.person.fullName(),
email: faker.internet.email(),
role: 'user',
createdAt: faker.date.past(),
}));
// Usage:
const user = userFactory.build();
const admin = userFactory.build({ role: 'admin' });
const users = userFactory.buildList(10);
pytest fixture factory:
import pytest
from faker import Faker
fake = Faker()
Faker.seed(42)
@pytest.fixture
def make_user():
def _make_user(**overrides):
defaults = {
"name": fake.name(),
"email": fake.email(),
"age": fake.random_int(min=18, max=99),
}
return {**defaults, **overrides}
return _make_user
def test_user_validation(make_user):
user = make_user(age=17)
assert validate_age(user) is False
Edge case data collection:
export const edgeCases = {
strings: ['', ' ', '\t\n', 'a'.repeat(10000), '<script>alert(1)</script>', # 10000: 10 seconds in ms
"Robert'); DROP TABLE users;--", '\u0000null\u0000byte'],
numbers: [0, -0, -1, Number.MAX_SAFE_INTEGER, NaN, Infinity, -Infinity],
dates: [new Date(0), new Date('2024-02-29'), new Date('9999-12-31')], # 2024: 9999 = configured value
};
Resources
1---2name: generating-test-data3description: Generate realistic test data including edge cases and boundary conditions. Use when creating realistic fixtures or edge case test data. Trigger with phrases like "generate test data", "create fixtures", or "setup test database".4license: MIT5---6# Test Data Generator
7
8## Overview
9
10Generate realistic, type-safe test data including fixtures, factory functions, seed datasets, and edge case values. Supports Faker.js, Factory Bot patterns, Fishery (TypeScript factories), pytest fixtures, and database seed scripts.
11
12## Prerequisites
13
14- Data generation library installed (Faker.js/@faker-js/faker, Fishery, factory-boy for Python, or JavaFaker)
15- Database schema or TypeScript/Python type definitions for the data models
16- Test framework with fixture support (Jest, pytest, JUnit)
17- Seed management for reproducible random data (`faker.seed()`)
18- Database client for seed data insertion (if generating database fixtures)
19
20## Instructions
21
221. Read the project's data models, TypeScript interfaces, database schemas, or ORM definitions to understand the shape of all entities.
232. For each entity, create a factory function that produces a valid default instance:
24 - Use Faker methods matched to field semantics (e.g., `faker.person.fullName()` for names, `faker.internet.email()` for emails).
25 - Provide sensible defaults for required fields.
26 - Allow overrides via a partial parameter for test-specific customization.
27 - Set a deterministic seed for reproducibility (`faker.seed(12345)`).
283. Generate edge case data variants for each entity:
29 - **Empty values**: Empty strings, null, undefined, empty arrays.
30 - **Boundary values**: Maximum string length, integer overflow, zero, negative numbers.
31 - **Unicode and i18n**: Names with accents, CJK characters, RTL text, emoji.
32 - **Adversarial inputs**: SQL injection strings, XSS payloads, excessively long strings.
33 - **Temporal edge cases**: Leap years, timezone boundaries, epoch zero, far-future dates.
344. Create relationship factories that build connected entity graphs:
35 - A user factory that also creates associated addresses and orders.
36 - Configurable depth to avoid infinite recursion.
37 - Lazy evaluation for optional relationships.
385. Generate database seed files for integration tests:
39 - SQL insert scripts or ORM seed functions.
40 - Idempotent operations (use `ON CONFLICT` or `INSERT IF NOT EXISTS`).
41 - Separate seed sets for different test scenarios (empty state, populated state, edge cases).
426. Write fixture files in JSON, YAML, or TypeScript for static test data:
43 - Group fixtures by test scenario.
44 - Include both valid and invalid data sets.
457. Validate generated data against the schema to ensure factories remain in sync with model changes.
46
47## Output
48
49- Factory function files (one per entity) in `test/factories/` or `tests/factories/`
50- Edge case data collections covering boundaries and adversarial inputs
51- Database seed scripts for integration test environments
52- JSON/YAML fixture files for static test data
53- Factory index file exporting all factories for easy test imports
54
55## Error Handling
56
57| Error | Cause | Solution |
58|-------|-------|---------|
59| Factory produces invalid data | Schema changed but factory not updated | Add a validation step that runs the factory output through the schema validator |
60| Duplicate unique values | Faker generates collisions in small datasets | Use sequential IDs or append a counter; increase Faker's unique retry limit |
61| Database seed fails on foreign key | Seed insertion order violates referential integrity | Sort seed operations topologically by dependency; disable FK checks during seeding |
62| Factory recursion overflow | Circular relationships (User -> Order -> User) | Limit relationship depth; use lazy references; break cycles with ID-only references |
63| Non-deterministic test failures | Random seed not set consistently | Call `faker.seed()` in `beforeAll` or at factory module level; document seed values |
64
65## Examples
66
67**TypeScript factory with Fishery:**
68
69```typescript
70import { Factory } from 'fishery';
71import { faker } from '@faker-js/faker';
72
73interface User {
74 id: string;
75 name: string;
76 email: string;
77 role: 'admin' | 'user';
78 createdAt: Date;
79}
80
81export const userFactory = Factory.define<User>(({ sequence }) => ({
82 id: `user-${sequence}`,
83 name: faker.person.fullName(),
84 email: faker.internet.email(),
85 role: 'user',
86 createdAt: faker.date.past(),
87}));
88
89// Usage:
90const user = userFactory.build();
91const admin = userFactory.build({ role: 'admin' });
92const users = userFactory.buildList(10);
93```
94
95**pytest fixture factory:**
96
97```python
98import pytest
99from faker import Faker
100
101fake = Faker()
102Faker.seed(42)
103
104@pytest.fixture
105def make_user():
106 def _make_user(**overrides):
107 defaults = {
108 "name": fake.name(),
109 "email": fake.email(),
110 "age": fake.random_int(min=18, max=99),
111 }
112 return {**defaults, **overrides}
113 return _make_user
114
115def test_user_validation(make_user):
116 user = make_user(age=17)
117 assert validate_age(user) is False
118```
119
120**Edge case data collection:**
121
122```typescript
123export const edgeCases = {
124 strings: ['', ' ', '\t\n', 'a'.repeat(10000), '<script>alert(1)</script>', # 10000: 10 seconds in ms
125 "Robert'); DROP TABLE users;--", '\u0000null\u0000byte'],
126 numbers: [0, -0, -1, Number.MAX_SAFE_INTEGER, NaN, Infinity, -Infinity],
127 dates: [new Date(0), new Date('2024-02-29'), new Date('9999-12-31')], # 2024: 9999 = configured value
128};
129```
130
131## Resources
132
133- Faker.js: https://fakerjs.dev/
134- Fishery (TypeScript factories): https://github.com/thoughtbot/fishery
135- factory_boy (Python): https://factoryboy.readthedocs.io/
136- Chance.js: https://chancejs.com/
137- Test data management patterns: https://martinfowler.com/bliki/ObjectMother.html