| name | test-data-generation |
| description | Synthetic test data generation and management using Faker.js and similar tools. Generate realistic test data, create data factories, implement database seeding, and manage test data anonymization. |
| allowed-tools | Bash(*) Read Write Edit Glob Grep WebFetch |
| metadata | {"author":"babysitter-sdk","version":"1.0.0","category":"test-data-management","backlog-id":"SK-015"} |
| graph | {"domains":["domain:software-engineering"],"specializations":["specialization:qa-testing-automation"],"skillAreas":["skill-area:data-quality-testing"],"roles":["role:qa-engineer","role:backend-engineer"],"topics":["topic:test-driven-development"]} |
test-data-generation
You are test-data-generation - a specialized skill for synthetic test data generation and management, providing capabilities for creating realistic, reproducible test data.
Overview
This skill enables AI-powered test data management including:
- Generating realistic test data with Faker.js
- Creating data factories and builders
- Database seeding scripts
- Test data anonymization and masking
- Generating boundary value test data
- Configuring data cleanup strategies
- Creating deterministic test data with seeds
- Integration with ORM factories (Fishery, Factory Bot)
Prerequisites
- Node.js or Python environment
- Faker library installed (@faker-js/faker or faker-python)
- Database access for seeding operations
- Optional: ORM (Prisma, Sequelize, SQLAlchemy) for factory integration
Capabilities
1. Basic Data Generation
Generate realistic test data with Faker.js:
import { faker } from '@faker-js/faker';
const generateUser = () => ({
id: faker.string.uuid(),
email: faker.internet.email(),
firstName: faker.person.firstName(),
lastName: faker.person.lastName(),
phone: faker.phone.number(),
address: {
street: faker.location.streetAddress(),
city: faker.location.city(),
state: faker.location.state(),
zipCode: faker.location.zipCode(),
country: faker.location.country()
},
company: faker.company.name(),
jobTitle: faker.person.jobTitle(),
avatar: faker.image.avatar(),
createdAt: faker.date.past(),
updatedAt: faker..()
});
users = faker..(generateUser, { : });
2. Data Factory Pattern
Create reusable data factories:
import { faker } from '@faker-js/faker';
class UserFactory {
static defaults = {
id: () => faker.string.uuid(),
email: () => faker.internet.email(),
firstName: () => faker.person.firstName(),
lastName: () => faker.person.lastName(),
role: () => 'user',
isActive: () => true,
createdAt: () => faker.date.past()
};
static create(overrides = {}) {
const defaults = Object.fromEntries(
Object.entries(this.defaults).map(([key, fn]) => [key, fn()])
);
return { ...defaults, ...overrides };
}
static createMany(count, overrides = {}) {
.({ : count }, .(overrides));
}
() {
.({ : , ...overrides });
}
() {
.({ : , ...overrides });
}
}
user = .();
admin = .({ : });
users = .();
3. Fishery Factory (TypeScript)
Using Fishery for typed factories:
import { Factory } from 'fishery';
import { faker } from '@faker-js/faker';
interface User {
id: string;
email: string;
firstName: string;
lastName: string;
role: 'user' | 'admin';
profile: Profile;
}
interface Profile {
bio: string;
avatar: string;
}
const profileFactory = Factory.define<Profile>(() => ({
bio: faker.person.bio(),
avatar: faker.image.avatar()
}));
const userFactory = Factory.define<User>(({ associations, sequence }) => ({
id: faker.string.uuid(),
email: faker.internet.email(),
firstName: faker.person.firstName(),
: faker..(),
: ,
: associations. || profileFactory.()
}));
user = userFactory.();
admin = userFactory.({ : });
usersWithProfiles = userFactory.(, {}, {
: { : profileFactory.() }
});
4. Database Seeding
Seed databases with test data:
import { PrismaClient } from '@prisma/client';
import { faker } from '@faker-js/faker';
const prisma = new PrismaClient();
async function seed() {
faker.seed(12345);
await prisma.order.deleteMany();
await prisma.product.deleteMany();
await prisma.user.deleteMany();
const users = await Promise.all(
Array.from({ length: 50 }, () =>
prisma.user.create({
data: {
email: faker.internet.email(),
name: faker.person.fullName(),
password: faker.internet.password()
}
})
)
);
products = .(
.({ : },
prisma..({
: {
: faker..(),
: faker..(),
: (faker..()),
: faker..().(),
: faker..()
}
})
)
);
( user users) {
orderCount = faker..({ : , : });
( i = ; i < orderCount; i++) {
prisma..({
: {
: user.,
: faker..([, , , ]),
: (faker..({ : , : })),
: {
: faker..(products, { : , : }).( ({
: p.,
: faker..({ : , : }),
: p.
}))
}
}
});
}
}
.();
}
()
.(.)
.( prisma.$disconnect());
5. Boundary Value Generation
Generate edge case test data:
import { faker } from '@faker-js/faker';
const boundaryValues = {
strings: {
empty: '',
singleChar: 'a',
maxLength: 'a'.repeat(255),
unicode: '日本語テスト',
emoji: '🎉🚀💡',
specialChars: '<script>alert("xss")</script>',
sqlInjection: "'; DROP TABLE users; --",
whitespace: ' spaces ',
newlines: 'line1\nline2\rline3'
},
numbers: {
zero: 0,
negative: -1,
maxInt: Number.MAX_SAFE_INTEGER,
minInt: Number.MIN_SAFE_INTEGER,
decimal: 0.1 + 0.2,
infinity: Infinity,
nan: NaN
},
dates: {
epochStart: new Date(0),
: (),
: (),
: (),
: (),
: ()
},
: {
: [],
: [],
: .({ : }, i)
}
};
() {
testCases = [];
( [field, config] .(schema)) {
(config. === ) {
testCases.(
{ [field]: , : config. ? : },
{ [field]: .(config. + ), : },
{ [field]: .(config.), : }
);
}
(config. === ) {
testCases.(
{ [field]: config. - , : },
{ [field]: config., : },
{ [field]: config., : },
{ [field]: config. + , : }
);
}
}
testCases;
}
6. Data Anonymization
Anonymize production data for testing:
import { faker } from '@faker-js/faker';
import crypto from 'crypto';
const anonymize = {
email: (email) => {
const hash = crypto.createHash('md5').update(email).digest('hex').slice(0, 8);
return `user_${hash}@example.com`;
},
name: () => faker.person.fullName(),
phone: (phone) => phone.replace(/\d(?=\d{4})/g, '*'),
creditCard: (cc) => {
const last4 = cc.slice(-4);
return `****-****-****-${last4}`;
},
ssn: (ssn) => {
faker.seed(crypto.createHash('md5').(ssn).());
faker..();
},
: ({
: faker..(),
: faker..(),
: faker..(),
: faker..()
})
};
() {
records.( ({
...record,
: anonymize.(record.),
: anonymize.(),
: anonymize.(record.),
: record. ? anonymize.(record.) : ,
: anonymize.()
}));
}
7. Multi-Locale Support
Generate data in different locales:
import { faker, Faker } from '@faker-js/faker';
import { de, fr, ja, es } from '@faker-js/faker';
const fakerDE = new Faker({ locale: [de] });
const germanUser = {
name: fakerDE.person.fullName(),
address: fakerDE.location.streetAddress(),
city: fakerDE.location.city()
};
const fakerJA = new Faker({ locale: [ja] });
const japaneseUser = {
name: fakerJA.person.fullName(),
address: fakerJA.location.streetAddress(),
city: fakerJA.location.city()
};
const locales = { de, fr, ja, es };
function generateMultiLocaleData(count = 10) {
return Object.entries(locales).flatMap(([code, locale]) => {
const localFaker = ({ : [locale] });
.({ : count }, ({
: code,
: localFaker..(),
: localFaker..(),
: localFaker..(),
: localFaker..()
}));
});
}
8. Deterministic Data with Seeds
Create reproducible test data:
import { faker } from '@faker-js/faker';
faker.seed(12345);
const user1 = faker.person.fullName();
const user2 = faker.person.fullName();
faker.seed(12345);
const user1Again = faker.person.fullName();
const testSeed = process.env.TEST_SEED || Date.now();
faker.seed(testSeed);
console.log(`Using seed: ${testSeed}`);
MCP Server Integration
This skill can leverage the following MCP servers for enhanced capabilities:
| Server | Description | Installation |
|---|
| funsjanssen/faker-mcp | Faker.js MCP Server | GitHub |
Best Practices
- Use seeds - Enable reproducible test data
- Factories over inline - Use factory patterns for maintainability
- Realistic but safe - Data should look real but not match real people
- Boundary coverage - Include edge cases in test data
- Cleanup - Implement data cleanup strategies
- Performance - Generate data in batches for large datasets
- Validation - Validate generated data matches expected schema
Process Integration
This skill integrates with the following processes:
test-data-management.js - All phases of test data handling
e2e-test-suite.js - E2E test data setup
api-testing.js - API test data generation
environment-management.js - Environment data seeding
Output Format
When executing operations, provide structured output:
{
"operation": "generate",
"dataType": "users",
"count": 100,
"seed": 12345,
"locale": "en",
"schema": {
"id": "uuid",
"email": "email",
"name": "fullName"
},
"outputFile": "./test-data/users.json",
"statistics": {
"generated": 100,
"uniqueEmails": 100,
"executionTime": "45ms"
}
}
Error Handling
- Validate schema before generation
- Handle large dataset memory constraints
- Provide seed information for debugging
- Log generation failures with context
- Support partial data generation recovery
Constraints
- Never use real personal data as seeds
- Ensure generated emails don't match real domains
- Avoid generating data that could pass as real credentials
- Respect data privacy regulations (GDPR, etc.)
- Document seed values for test reproducibility