第19回: Seederとテストデータ管理 — 「誰でも同じ初期データ」で開発を安定させる

章: 第2章: データベース応用

「自分の環境でしか動かない」——テストデータの差異が引き起こす問題

開発者Aはユーザーを手動で5件登録している。開発者BはDB初期化後に1件しかない。CI環境には何もない——。こうした「環境ごとのデータ差異」がテスト結果の不一致や、動作確認の手戻りを引き起こします。

Seederを使うと php artisan db:seed コマンド一発で誰でも同じ初期データを再現できます。

Seederの実装


<?php
use Illuminate\Database\Seeder;
class UserSeeder extends Seeder {
    public function run(): void {
        User::factory()->count(10)->create();
    }
}
class UserFactory extends Factory {
    public function definition(): array {
        return [
            'name'  => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
        ];
    }
}
// 実行: php artisan db:seed

手動データ投入 vs Seeder

観点 手動でデータ投入 Seederを使う
再現性 環境ごとに異なる db:seed で誰でも同じ
チーム開発 誰かのデータが違う 統一された初期状態
CI/CD 自動化できない --seed オプションで組み込める
リセット データが混ざる migrate:fresh --seed で完全初期化

チェックポイント: php artisan migrate:fresh --seed でテーブルをリセットして初期データを投入し直せます。開発中のデータ汚染をリセットするのに便利です。

Factoryの状態(State)を使う


<?php
class UserFactory extends Factory {
    public function definition(): array {
        return [
            'name'     => fake()->name(),
            'email'    => fake()->unique()->safeEmail(),
            'role'     => 'user',
            'verified' => true,
        ];
    }

    // 管理者ユーザー用のState
    public function admin(): static {
        return $this->state(['role' => 'admin']);
    }
}

// DatabaseSeeder
class DatabaseSeeder extends Seeder {
    public function run(): void {
        User::factory()->count(50)->create();
        User::factory()->admin()->count(3)->create();
    }
}

チェックポイント: FactoryのStateを使うと「管理者5名、一般ユーザー50名」のような現実的なデータセットを宣言的に作れます。

まとめ & 次のステップ

  • Seederはテスト・開発用の初期データをコードで管理し、誰でも再現できる
  • Factoryを組み合わせることで現実的なデータセットをランダム生成できる
  • migrate:fresh --seed でいつでもクリーンな初期状態に戻せる

次回は論理削除とソフトデリートを学びます。物理削除せずに「削除済み」として扱い、データを安全に保持する方法です。

Related Articles