開発環境で「それっぽいテストデータ山盛りにしたり空にしたい」あなたへ——Seeder と Factory を使って秒でデモデータを用意し、ストレスフリーなテスト環境を手に入れましょう。
この記事は ライトに読めるのに実用的 を合言葉に、セットアップから応用テクまで一気にまとめます。
- 1. そもそも Seeder / Factory って何者?
- 2. セットアップ
- 2.1. Fakerのインストール
- 3. SeederとFactoryをひな形生成
- 4. 基本の Factory 定義 – Book を 30 冊量産
- 5. Seederで呼び出せる便利さ
- 6. 応用テク – State, Sequence, Relation の三種盛り
- 6.1. state() で属性の差分だけ上書き
- 6.2. sequence() でパターン回し撃ち
- 6.3. Relationを指定して関連モデルにもレコードを量産
- 6.3.1. Book モデルのリレーション(※1)
- 6.4. database/factories/ReviewFactory.php を追加(※2)
- 7. テスト連携 – RefreshDatabase だけが正義ではない
- 7.1. RefreshDatabase の例
- 7.2. DatabaseTransactions の例
そもそも Seeder / Factory って何者?
Seeder と Factory は、Laravel データ生成界のずっとも。
Factory が「こういうスペックで量産するわ」と自動工作機を持ち込み、
Seeder が「んじゃこのタイミングで50連投!」と DB にタネをばら撒く。
この 2 役を使いこなせば、退屈な INSERT 文の手打ちとは即・決別できます
用語 | ざっくり役割 | 覚え方 |
---|---|---|
Factory | モデル 1 件分の 設計図 & 自動生成マシーン | 工場:1 クリックで製品を量産 |
Seeder | 量産したデータを いつ・どの順番で・何件流し込むか を管理する司令塔 | 種まき人:畑(DB)に種(データ)をまく |

Factory が「どうやって作る?」、Seeder が「いつ何個作る?」を担当するんだね〜。
セットアップ
開発環境をシード対応モードに切り替えるためのクイックスタート。
composer.json の健診から Faker 追加、Seeder & Factory 雛形生成まで、5 分で終わる初期設定をここで一気に片付けます。
Fakerのインストール
ダミーデータの値を作るツールです。
👉️ Faker活用ライトガイド – “それっぽい” ダミーデータを 5 秒で錬成する
SeederとFactoryをひな形生成
php artisan make:seeder BookSeeder
php artisan make:factory BookFactory --model=Book
これで database/seeders
と database/factories
にファイルが生えます。
基本の Factory 定義 – Book を 30 冊量産
database/factories/BookFactory.php
BookFactory ではタイトル・著者・刊行日といった本らしい属性を Faker で自動生成。量産した30冊を使って一覧ページやリレーション表示をサクッと検証できます。
<?php
use Illuminate\Database\Eloquent\Factories\Factory;
class BookFactory extends Factory
{
protected $model = Book::class;
public function definition(): array
{
return [
'title' => $this->faker->sentence(),
'author' => $this->faker->name(),
'published_at' => $this->faker->dateTimeBetween('-10 years'),
'isbn' => $this->faker->isbn13(),
'summary' => $this->faker->paragraph(),
];
}
}
量産コマンド(Tinker や Seeder から呼ぶ)
Book::factory()->count(30)->create();
これだけで 30 行 INSERT 完了。ループ地獄と永別です。
Seederで呼び出せる便利さ
BookSeeder は BookFactory を呼び出して 30 冊のダミーデータを DB に一括投入する撒き役。
複数 Seeder を束ねれば php artisan db:seed
一発でフルデータセットが完成する快感を体感できます!
class BookSeeder extends Seeder
{
public function run(): void
{
Book::factory()->count(30)->create();
}
}
次に、DatabaseSeeder でまとめておくと全体シードがラク。
class DatabaseSeeder extends Seeder
{
public function run(): void
{
$this->call([
BookSeeder::class,
UserSeeder::class,
// ここに他 Seeder を追加
]);
}
}
Seederを準備したら
php artisan migrate:fresh --seed # テーブル再作成 + 全Seeder実行
上記コマンドを実行してテーブルにデータを入力します。

何度も使える最強のSeederをつくろ〜!
応用テク – State, Sequence, Relation の三種盛り
Factory にスパイスを振りかけて、単調なダミーデータを一気に多様化させる3つの技。
- state() … 1 パターンだけ属性を上書き
- sequence() … 属性パターンを順番にローテーション
- リレーションメソッド … 関連モデルを同時に量産
state()
で属性の差分だけ上書き
👉️ 1 冊だけgenre
がsci-fi
に固定された Book レコードを生成
Book::factory()
->state(fn () => ['genre' => 'sci-fi'])
->create();
sequence()
でパターン回し撃ち
👉️ genre
が fantasy → mystery → sci-fi
と順番にローテーションしながら 6 冊生成される
Book::factory()
->count(6)
->sequence(
['genre' => 'fantasy'],
['genre' => 'mystery'],
['genre' => 'sci-fi']
)
->create();
Relationを指定して関連モデルにもレコードを量産
👉️ 各BookにReviewが5件ずつ関連付けられて生成される
Book::factory()
->hasReviews(5) // ReviewFactory も自動呼び出し
->create();
関係を成り立たせるための準備
- Book モデルに
reviews()
のhasMany
リレーションを追加。※1 - ReviewFactory を作成し、
book_id
を必ずセット(Book::factory()
で OK)。※2 - 上記 2 点が揃うと、
hasReviews(5)
が ReviewFactory を 5 回呼び出し、生成後に外部キーを自動で書き込みます。
Book モデルのリレーション(※1)
class Book extends Model
{
use HasFactory;
public function reviews(): HasMany
{
return $this->hasMany(Review::class);
}
}
database/factories/ReviewFactory.php
を追加(※2)
use Illuminate\Database\Eloquent\Factories\Factory;
class ReviewFactory extends Factory
{
protected $model = Review::class;
public function definition(): array
{
return [
'book_id' => Book::factory(), // Book と紐付け
'rating' => $this->faker->numberBetween(1, 5),
'comment' => $this->faker->sentence(),
];
}
}
テスト連携 – RefreshDatabase だけが正義ではない
テストごとに DB をリセットする方法は主に 2 種類 あります。
Trait | 仕組み | どんな時に便利? |
RefreshDatabase | 各テスト前後で migrate:fresh を実行。Seeder も走らせてフルリセット | 外部キー制約・マルチ DB・ファイルストレージなどを絡めた統合テストに◎ |
DatabaseTransactions | 各テストをトランザクションで包み、終了時に自動ロールバック | 単体テスト中心で高速に回したいときに◎ |
RefreshDatabase の例
このテストは RefreshDatabase を採用。毎回 migrate:fresh
と Seeder 実行で DB をゼロから再構築するため、外部キー制約や複数接続を含む統合テストに向く。ただし実行時間はやや長め。
use Illuminate\Foundation\Testing\RefreshDatabase;
class HomeScreenTest extends TestCase
{
use RefreshDatabase;
public function test_it_shows_books()
{
$this->seed(BookSeeder::class);
$response = $this->get('/');
$response->assertStatus(200);
}
}
DatabaseTransactions の例
こちらは DatabaseTransactions を使用。各テストをトランザクションでラップし、終了時に自動ロールバックするので高速。ただし非同期ジョブや別接続が絡むケースではロールバックが届かない点に注意。
use Illuminate\Foundation\Testing\DatabaseTransactions;
class HomeScreenFastTest extends TestCase
{
use DatabaseTransactions;
public function test_it_shows_books_quickly()
{
Book::factory()->create();
$response = $this->get('/');
$response->assertStatus(200);
}
}

キュー処理や別コネクションが飛び交うテストではトランザクションが効かないからRefreshDatabaseを選ぶのがオススメだけど
テーブル多いなら、テーブル作ったままテストで追加したレコードだけを消せるDatabaseTransactionも便利だよ〜。
-
外部キー制約でエラーになる (
SQLSTATE[23000]: Integrity constraint violation
) -
\Illuminate\Database\Eloquent\Model::unguard()
でガードを外すか、Seeder の実行順序を見直して 親テーブルを先に作成 しましょう。
-
Faker の
unique()
が枯渇して Unique constraint violation が起きる -
FakerのUniqueには、上限があります。(文字列は数千〜数万辞書の程度によります)
コメントを残す