Database Seeding & Fixture Management
debt(d7/e5/b5/t5)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints indicate automated detection is 'no' and the tools listed (laravel-factories, doctrine-fixtures) are framework features rather than static analysis tools. Raw INSERT SQL in test setup, shared test databases, and production data imports are patterns only visible through manual code review or when tests start failing intermittently in CI.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix suggests replacing raw SQL with database factories, but this requires creating factory classes, defining states, updating all test files that seed data manually, and establishing proper database reset patterns. Not a one-line fix, but typically contained within the test infrastructure layer.
Closest to 'persistent productivity tax' (b5). Database seeding patterns affect every developer writing tests and every CI run. Poor seeding choices (production dumps, hardcoded IDs, no factory states) create ongoing friction: slow test suites, flaky CI, difficult local setup. The applies_to shows this spans web and cli contexts, meaning the pattern pervades the entire test infrastructure.
Closest to 'notable trap' (t5). The misconception explicitly states 'Production data dumps are better than seeded test data' — this is a documented gotcha that many developers eventually learn the hard way. Using prod dumps seems safer (real data!) but introduces PII issues, staleness, and non-deterministic tests. The common_mistakes around hardcoded IDs and shared databases are additional traps that contradict intuitions from simpler testing scenarios.
Also Known As
TL;DR
Explanation
Database seeding creates consistent data states for development, testing, and demos. Patterns: Seeders (run once to populate dev/staging), Factories (define blueprints for generating model instances with realistic fake data — Faker library), Fixtures (static data files loaded for tests). Factory best practices: realistic but anonymised data, factory states for different scenarios (admin user, suspended user), and factory relationships. Test databases reset between test runs (DatabaseTransactions or RefreshDatabase) using seeders for required reference data.
Common Misconception
Why It Matters
Common Mistakes
- Seeding production-like volumes in tests — 100,000 seeded rows makes tests slow; seed only what tests need.
- Hardcoded IDs in seeds and factories — brittle tests that break when IDs change.
- No factory states — creating 'admin user' vs 'regular user' via attributes instead of named states.
- Shared database between tests — never share state; each test must reset or use transactions.
Code Examples
// Manual test data in tests — brittle and slow:
class OrderTest extends TestCase {
public function setUp(): void {
$pdo->exec("INSERT INTO users VALUES (1, 'Alice', 'alice@example.com')");
$pdo->exec("INSERT INTO orders VALUES (1, 1, 99.99, 'pending')");
// ID 1 hardcoded — breaks when other tests run first
}
}
// Laravel factories — flexible, realistic, relationship-aware:
class UserFactory extends Factory {
public function definition(): array {
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'password' => Hash::make('password'),
];
}
public function admin(): static {
return $this->state(['role' => 'admin']);
}
public function withOrders(int $count = 3): static {
return $this->has(Order::factory()->count($count));
}
}
// Test: one line creates everything needed:
$user = User::factory()->admin()->withOrders(3)->create();