
Test Data Management
- 12 installs
- 213 repo stars
- Updated August 4, 2026
- yonatangross/orchestkit
Helps with testing & qa tasks.
About
test-data-management is a Claude Code skill for testing & qa. It helps developers move faster with AI-assisted coding.
- test-data-management
- Testing & QA
- AI-coding skill
Test Data Management by the numbers
- 12 all-time installs (skills.sh)
- Ranked #1,527 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/yonatangross/orchestkit --skill test-data-managementAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 12 |
|---|---|
| repo stars | ★ 213 |
| Last updated | August 4, 2026 |
| Repository | yonatangross/orchestkit ↗ |
What it does
Helps with testing & qa tasks.
Files
Test Data Management
Create and manage test data effectively.
Factory Pattern (Python)
from factory import Factory, Faker, SubFactory, LazyAttribute
from app.models import User, Analysis
class UserFactory(Factory):
class Meta:
model = User
email = Faker('email')
name = Faker('name')
created_at = Faker('date_time_this_year')
class AnalysisFactory(Factory):
class Meta:
model = Analysis
url = Faker('url')
status = 'pending'
user = SubFactory(UserFactory)
@LazyAttribute
def title(self):
return f"Analysis of {self.url}"
# Usage
user = UserFactory()
analysis = AnalysisFactory(user=user, status='completed')Factory Pattern (TypeScript)
import { faker } from '@faker-js/faker';
interface User {
id: string;
email: string;
name: string;
}
const createUser = (overrides: Partial<User> = {}): User => ({
id: faker.string.uuid(),
email: faker.internet.email(),
name: faker.person.fullName(),
...overrides,
});
const createAnalysis = (overrides = {}) => ({
id: faker.string.uuid(),
url: faker.internet.url(),
status: 'pending',
userId: createUser().id,
...overrides,
});
// Usage
const user = createUser({ name: 'Test User' });
const analysis = createAnalysis({ userId: user.id, status: 'completed' });JSON Fixtures
// fixtures/users.json
{
"admin": {
"id": "user-001",
"email": "admin@example.com",
"role": "admin"
},
"basic": {
"id": "user-002",
"email": "user@example.com",
"role": "user"
}
}import json
import pytest
@pytest.fixture
def users():
with open('fixtures/users.json') as f:
return json.load(f)
def test_admin_access(users):
admin = users['admin']
assert admin['role'] == 'admin'Database Seeding
# seeds/test_data.py
async def seed_test_database(db: AsyncSession):
"""Seed database with test data."""
# Create users
users = [
UserFactory.build(email=f"user{i}@test.com")
for i in range(10)
]
db.add_all(users)
# Create analyses for each user
for user in users:
analyses = [
AnalysisFactory.build(user_id=user.id)
for _ in range(5)
]
db.add_all(analyses)
await db.commit()
@pytest.fixture
async def seeded_db(db_session):
await seed_test_database(db_session)
yield db_sessionFixture Composition
@pytest.fixture
def user():
return UserFactory()
@pytest.fixture
def user_with_analyses(user):
analyses = [AnalysisFactory(user=user) for _ in range(3)]
return {"user": user, "analyses": analyses}
@pytest.fixture
def completed_workflow(user_with_analyses):
for analysis in user_with_analyses["analyses"]:
analysis.status = "completed"
return user_with_analysesTest Data Isolation
@pytest.fixture(autouse=True)
async def clean_database(db_session):
"""Reset database between tests."""
yield
# Clean up after test
await db_session.execute("TRUNCATE users, analyses CASCADE")
await db_session.commit()Key Decisions
| Decision | Recommendation |
|---|---|
| Strategy | Factories over fixtures |
| Faker | Use for realistic random data |
| Scope | Function-scoped for isolation |
| Cleanup | Always reset between tests |
Common Mistakes
- Shared state between tests
- Hard-coded IDs (conflicts)
- No cleanup after tests
- Over-complex fixtures
Related Skills
unit-testing- Test patternsintegration-testing- Database testsdatabase-schema-designer- Schema design
Capability Details
fixture-generation
Keywords: fixture, test fixture, pytest fixture, conftest Solves:
- Create reusable test fixtures
- Implement fixture composition
- Handle fixture cleanup
factory-patterns
Keywords: factory, FactoryBoy, test factory, model factory Solves:
- Generate test data with factories
- Implement factory inheritance
- Create related object graphs
data-seeding
Keywords: seed, seed data, database seed, initial data Solves:
- Seed databases for testing
- Create consistent test environments
- Implement idempotent seeding
cleanup-strategies
Keywords: cleanup, teardown, reset, isolation Solves:
- Clean up test data after runs
- Implement transaction rollback
- Ensure test isolation
data-anonymization
Keywords: anonymize, faker, synthetic data, mock data Solves:
- Generate realistic fake data
- Anonymize production data for tests
- Create synthetic datasets
Test Data Management Checklist
Fixtures
- [ ] Use factories over hardcoded data
- [ ] Minimal required fields
- [ ] Randomize non-essential data
- [ ] Version control fixtures
Data Generation
- [ ] Faker for realistic data
- [ ] Consistent seeds for reproducibility
- [ ] Edge case generators
- [ ] Bulk generation for perf tests
Database
- [ ] Transaction rollback for isolation
- [ ] Per-test database when needed
- [ ] Proper cleanup order
- [ ] Handle foreign keys
Cleanup
- [ ] Clean up after each test
- [ ] Handle test failures
- [ ] Verify clean state
- [ ] Prevent data leaks
Best Practices
- [ ] No test interdependencies
- [ ] Factories over fixtures
- [ ] Meaningful test data
- [ ] Document data requirements
Factory Patterns for Test Data
Generate consistent, realistic test data with factory patterns.
Implementation
import factory
from factory import Faker, SubFactory, LazyAttribute, Sequence
from datetime import datetime, timedelta
from app.models import User, Organization, Project
class OrganizationFactory(factory.Factory):
"""Factory for Organization entities."""
class Meta:
model = Organization
id = Sequence(lambda n: f"org-{n:04d}")
name = Faker("company")
slug = LazyAttribute(lambda o: o.name.lower().replace(" ", "-"))
created_at = Faker("date_time_this_year")
class UserFactory(factory.Factory):
"""Factory for User entities with organization relationship."""
class Meta:
model = User
id = Sequence(lambda n: f"user-{n:04d}")
email = Faker("email")
name = Faker("name")
organization = SubFactory(OrganizationFactory)
is_active = True
created_at = Faker("date_time_this_month")
@LazyAttribute
def username(self):
return self.email.split("@")[0]
class ProjectFactory(factory.Factory):
"""Factory with traits for different project states."""
class Meta:
model = Project
id = Sequence(lambda n: f"proj-{n:04d}")
name = Faker("catch_phrase")
owner = SubFactory(UserFactory)
status = "active"
class Params:
archived = factory.Trait(
status="archived",
archived_at=Faker("date_time_this_month")
)
completed = factory.Trait(
status="completed",
completed_at=Faker("date_time_this_week")
)Usage Patterns
# Basic creation
user = UserFactory()
# Override specific fields
admin = UserFactory(email="admin@company.com", is_active=True)
# Use traits
archived_project = ProjectFactory(archived=True)
# Batch creation
users = UserFactory.create_batch(10)
# Build without persistence (in-memory only)
temp_user = UserFactory.build()Checklist
- [ ] Use Sequence for unique identifiers
- [ ] Use SubFactory for related entities
- [ ] Use LazyAttribute for computed fields
- [ ] Use Traits for common variations (archived, deleted, premium)
- [ ] Keep factories close to model definitions
- [ ] Document factory-specific test data assumptions
# Template: Factory Boy Configuration
# Usage: Copy to tests/factories.py and customize for your models
import random
from datetime import datetime, timedelta
import factory
from factory import Faker, LazyAttribute, Sequence, SubFactory
from factory.fuzzy import FuzzyChoice, FuzzyDecimal
# TODO: Import your SQLAlchemy models
# from app.models import User, Team, Project, Task
# ============================================================================
# BASE FACTORY (for SQLAlchemy integration)
# ============================================================================
class BaseFactory(factory.Factory):
"""Base factory with common patterns for all entities."""
class Meta:
abstract = True
@classmethod
def _create(cls, model_class, *args, **kwargs):
"""Override to add to session if using SQLAlchemy."""
# TODO: Uncomment for SQLAlchemy integration
# from tests.conftest import get_test_session
# session = get_test_session()
# obj = model_class(*args, **kwargs)
# session.add(obj)
# session.commit()
# return obj
return model_class(*args, **kwargs)
# ============================================================================
# ENTITY FACTORIES
# ============================================================================
class TeamFactory(BaseFactory):
"""Factory for Team entities."""
class Meta:
# TODO: model = Team
model = dict
id = Sequence(lambda n: f"team-{n:04d}")
name = Faker("company")
slug = LazyAttribute(lambda o: o["name"].lower().replace(" ", "-")[:20])
plan = FuzzyChoice(["free", "pro", "enterprise"])
created_at = Faker("date_time_between", start_date="-1y", end_date="now")
class UserFactory(BaseFactory):
"""Factory for User entities with relationships."""
class Meta:
# TODO: model = User
model = dict
id = Sequence(lambda n: f"user-{n:04d}")
email = Faker("email")
name = Faker("name")
role = FuzzyChoice(["admin", "member", "viewer"])
team = SubFactory(TeamFactory)
is_active = True
created_at = Faker("date_time_this_year")
@LazyAttribute
def username(obj):
return obj["email"].split("@")[0]
# Traits for common variations
class Params:
admin = factory.Trait(role="admin")
inactive = factory.Trait(is_active=False)
new_user = factory.Trait(
created_at=factory.LazyFunction(
lambda: datetime.now() - timedelta(days=random.randint(0, 7))
)
)
class ProjectFactory(BaseFactory):
"""Factory for Project entities with lifecycle states."""
class Meta:
# TODO: model = Project
model = dict
id = Sequence(lambda n: f"proj-{n:04d}")
name = Faker("catch_phrase")
description = Faker("paragraph", nb_sentences=2)
owner = SubFactory(UserFactory)
team = LazyAttribute(lambda o: o["owner"]["team"])
status = "active"
budget = FuzzyDecimal(1000, 100000, precision=2)
created_at = Faker("date_time_this_month")
class Params:
archived = factory.Trait(
status="archived",
archived_at=Faker("date_time_this_month")
)
completed = factory.Trait(
status="completed",
completed_at=Faker("date_time_this_week")
)
over_budget = factory.Trait(
budget=FuzzyDecimal(100, 500, precision=2)
)
class TaskFactory(BaseFactory):
"""Factory for Task entities with project relationship."""
class Meta:
# TODO: model = Task
model = dict
id = Sequence(lambda n: f"task-{n:04d}")
title = Faker("sentence", nb_words=6)
description = Faker("paragraph")
project = SubFactory(ProjectFactory)
assignee = LazyAttribute(lambda o: o["project"]["owner"])
priority = FuzzyChoice(["low", "medium", "high", "critical"])
status = "pending"
due_date = Faker("date_between", start_date="today", end_date="+30d")
class Params:
completed = factory.Trait(
status="completed",
completed_at=Faker("date_time_this_week")
)
overdue = factory.Trait(
status="pending",
due_date=Faker("date_between", start_date="-30d", end_date="-1d")
)
# ============================================================================
# BATCH CREATION HELPERS
# ============================================================================
def create_team_with_members(member_count: int = 5) -> dict:
"""Create a team with multiple members."""
team = TeamFactory()
admin = UserFactory(team=team, admin=True)
members = UserFactory.create_batch(member_count - 1, team=team)
return {"team": team, "admin": admin, "members": members}
def create_project_with_tasks(task_count: int = 10) -> dict:
"""Create a project with multiple tasks."""
project = ProjectFactory()
tasks = TaskFactory.create_batch(task_count, project=project)
return {"project": project, "tasks": tasks}
# ============================================================================
# USAGE EXAMPLES
# ============================================================================
if __name__ == "__main__":
# Basic creation
user = UserFactory()
print(f"Created user: {user}")
# With overrides
admin = UserFactory(email="admin@test.com", admin=True)
print(f"Created admin: {admin}")
# Using traits
inactive_user = UserFactory(inactive=True)
archived_project = ProjectFactory(archived=True)
# Batch creation
users = UserFactory.create_batch(5)
print(f"Created {len(users)} users")
# Complex scenario
team_data = create_team_with_members(10)
print(f"Team: {team_data['team']['name']} with {len(team_data['members'])} members")