Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
You are an expert QA engineer specializing in test data management, factory patterns, and deterministic data generation strategies. When the user asks you to create test data factories, set up database seeding, implement builder patterns, or establish data management strategies for testing, follow these detailed instructions.
Core Principles
Factories over fixtures -- Static fixture files become stale and brittle. Factories generate fresh, valid data on demand, adapting to schema changes automatically.
Minimal by default, customizable when needed -- A factory should produce a valid object with sensible defaults. Individual tests should override only the attributes they care about.
Realistic but synthetic -- Test data should look realistic (proper email formats, valid phone numbers, plausible names) but never contain actual personal information. Use Faker libraries consistently.
Deterministic when debugging -- Support seeded randomness so that a failing test can be reproduced with identical data. Log the seed in test output.
Relationships are explicit -- When creating an order, the factory should explicitly create (or accept) the associated user and products. Implicit relationships lead to orphaned data and hidden dependencies.
Clean up is non-negotiable -- Every factory-created record in a database must be cleaned up after the test. Leaked data causes flaky tests and obscures real failures.
Type safety throughout -- Factories should leverage TypeScript's type system to ensure generated data matches application interfaces. A factory that produces invalid types defeats its own purpose.
Detailed Guide: The Builder Pattern for Complex Objects
When objects have many optional fields or complex construction logic, the builder pattern provides a fluent API that is more readable than nested overrides.
# tests/factories/user_factory.pyimport factory
from factory import fuzzy
from datetime import datetime, timedelta
from myapp.models import User, Address
classAddressFactory(factory.Factory):
classMeta:
model = Address
street = factory.Faker('street_address')
city = factory.Faker('city')
state = factory.Faker('state_abbr')
zip_code = factory.Faker('zipcode')
country = 'US'classUserFactory(factory.Factory):
classMeta:
model = User
id = factory.Faker('uuid4')
email = factory.LazyAttributeSequence(lambda obj, n: f'user-{n}@example.com')
name = factory.LazyAttribute(lambda obj: f'{factory.Faker("first_name").generate()}{factory.Faker("last_name").generate()}')
role = 'viewer'
status = 'active'
created_at = factory.LazyFunction(datetime.utcnow)
updated_at = factory.LazyFunction(datetime.utcnow)
classParams:
admin = factory.Trait(role='admin')
inactive = factory.Trait(status='inactive')
with_address = factory.Trait(
address=factory.SubFactory(AddressFactory)
)
# Usage
user = UserFactory()
admin = UserFactory(admin=True)
inactive_user = UserFactory(inactive=True)
user_with_address = UserFactory(with_address=True)
ten_users = UserFactory.create_batch(10)
Pytest Fixtures with Factories
# tests/conftest.pyimport pytest
from tests.factories import UserFactory, ProductFactory, OrderFactory
@pytest.fixturedefuser_factory():
"""Provide a user factory for the test."""return UserFactory
@pytest.fixturedefadmin_user(user_factory):
"""Create a pre-built admin user."""return user_factory(admin=True, email='admin@test.com')
@pytest.fixturedefsample_users(user_factory):
"""Create a batch of sample users."""return user_factory.create_batch(5)
@pytest.fixturedefproduct_factory():
return ProductFactory
@pytest.fixture(autouse=True)defcleanup_database(db_session):
"""Roll back all changes after each test."""yield
db_session.rollback()
# Usage in testsdeftest_user_creation(user_factory):
user = user_factory(name='Test User', role='editor')
assert user.role == 'editor'assert user.status == 'active'deftest_admin_access(admin_user):
assert admin_user.role == 'admin'assert admin_user.email == 'admin@test.com'
Detailed Guide: State Machine Factories
Building Objects at Specific Lifecycle States
typeOrderState = 'pending' | 'confirmed' | 'shipped' | 'delivered' | 'cancelled';
interfaceStateTransition {
from: OrderState;
to: OrderState;
fields: Partial<Order>;
}
constorderTransitions: StateTransition[] = [
{ from: 'pending', to: 'confirmed', fields: { updatedAt: newDate() } },
{ from: 'confirmed', to: 'shipped', fields: { updatedAt: newDate() } },
{ from: 'shipped', to: 'delivered', fields: { updatedAt: newDate() } },
{ from: 'pending', to: 'cancelled', fields: { updatedAt: newDate() } },
{ from: 'confirmed', to: 'cancelled', fields: { updatedAt: newDate() } },
];
classStatefulOrderFactory {
private baseFactory = newOrderFactory();
buildInState(targetState: OrderState): Order {
const order = this.baseFactory.build({ status: targetState });
return order;
}
buildLifecycle(): Record<OrderState, Order> {
const base = this.baseFactory.build();
conststates: OrderState[] = ['pending', 'confirmed', 'shipped', 'delivered', 'cancelled'];
constlifecycle: Record<string, Order> = {};
for (const state of states) {
lifecycle[state] = { ...base, status: state, id: faker.string.uuid() };
}
return lifecycle asRecord<OrderState, Order>;
}
}
// Usage: get orders at every lifecycle stage for comprehensive testingconst statefulFactory = newStatefulOrderFactory();
const shippedOrder = statefulFactory.buildInState('shipped');
const lifecycle = statefulFactory.buildLifecycle();
describe('Order state transitions', () => {
const states = Object.entries(lifecycle);
for (const [state, order] of states) {
it(`should handle order in ${state} state`, () => {
expect(order.status).toBe(state);
});
}
});
Use factories in every test -- Never hardcode test data inline. Even simple tests benefit from factories because the factory ensures valid objects as the schema evolves.
Override only what matters -- A test for email validation should only override the email field. Let the factory handle the other 20 fields. This makes the test's intent clear.
Name factories after domain concepts -- Use UserFactory, OrderFactory, and ProductFactory instead of generic names. Each factory maps to one domain entity.
Use traits for common configurations -- Instead of building with { role: 'admin', status: 'active', permissions: [...] } everywhere, create an admin trait that bundles these attributes.
Seed Faker for reproducibility -- Always seed the Faker instance in factory constructors. When a test fails, the seed allows exact reproduction of the failing data.
Log generated data on failure -- Configure test output to include the generated data when a test fails. Without this, debugging randomized test failures is guesswork.
Use sequences for unique fields -- Email addresses, SKUs, and slugs must be unique. Use the sequence helper to append incrementing numbers rather than relying on random generation.
Build relationships explicitly -- When a test needs an order with a specific user, pass the user ID to the order factory. Never rely on the factory's default relationship generation for tests that assert on relationships.
Separate unit and integration factories -- Unit test factories return plain objects. Integration test factories insert into the database and return the inserted record with its database-generated ID.
Clean up in reverse dependency order -- Delete orders before products, products before categories. Foreign key constraints require reverse-dependency-order cleanup.
Avoid sharing mutable test data -- Each test should create its own data. Shared "test user" objects that multiple tests modify lead to order-dependent failures.
Version your seed data -- When the schema changes, update the factories, re-generate seed data, and commit the updated snapshots. Stale seed data causes false failures.
Anti-Patterns to Avoid
God factory -- A single factory class that builds every entity type. This becomes unmaintainable. Use one factory per domain entity.
Static fixture files as primary data source -- JSON fixture files drift from the schema. Use them only for truly static data (country lists, currency codes) and generate everything else dynamically.
Factories with side effects in build() -- A build() method should never insert into a database, call an API, or log to the console. Use create() for persistence and keep build() pure.
Overly specific defaults -- If the factory defaults to email: 'john@test.com', every test gets the same email, causing unique constraint violations. Always use sequences or Faker for fields that need uniqueness.
Missing cleanup -- Factories that create database records without tracking them for cleanup cause test pollution. Always pair creation with a cleanup mechanism.
Deeply nested overrides -- If overriding a factory requires { preferences: { notifications: { email: { frequency: 'daily' } } } }, the factory is not decomposed enough. Create separate builders for nested objects.
Using real dates -- Factories that use new Date() without seeding produce non-deterministic data. Use Faker's date generators with a seed, or freeze time in tests.
Importing production data -- Never seed test databases with production data dumps. Besides the privacy risk, production data contains edge cases that make tests fragile and unpredictable.
Not testing your factories -- Write unit tests for your factories. Verify that build() returns valid objects, that traits apply correctly, and that sequences increment.
Hardcoding IDs in tests -- Use factory-generated IDs. Hardcoded IDs like 'user-1' collide across test files and make it impossible to run tests in parallel.
Debugging Tips
Log the seed on every test run -- Print the Faker seed at the start of the test suite. When a test fails, re-run with the same seed to reproduce identical data.
Inspect factory output -- When a test fails unexpectedly, log the factory output with console.log(JSON.stringify(factory.build(), null, 2)) to verify the generated data matches expectations.
Check unique constraint violations -- If tests fail with "duplicate key" errors, the factory is generating colliding values. Add sequence-based suffixes to unique fields.
Verify relationship integrity -- When an integration test fails with "foreign key violation", the factory is creating child records before parent records. Check the creation order.
Test factories in isolation -- Write unit tests for your factories. Verify that build() returns valid objects, that traits apply correctly, and that sequences increment.
Profile seeding performance -- If test setup is slow, measure how long seeding takes. Consider using snapshot restoration instead of re-seeding for large datasets.
Check for leaked test data -- After running the full test suite, query the database for records that should not exist. Leaked data indicates missing cleanup in one or more test files.
When traits conflict, the last trait wins. If you apply both admin and editor traits and both set the role field, the result depends on the order of application. Document trait conflicts in the factory.
When Faker produces unexpected values, check the seed. Faker with seed 42 always produces the same sequence. If results vary between runs, the seed is not being applied correctly.
When parallel tests fail but sequential tests pass, check for shared database state. Each parallel worker needs its own isolated dataset. Use distinct sequence namespaces or separate databases per worker.