fakerphp/fakerでテストデータとシーダーを効率化する
概要
開発やテストで「それっぽいダミーデータ」を大量に用意したい場面は多い。手でレコードを打ち込むのは非効率で、本番データをコピーして使うと個人情報の混入事故にもつながる。
fakerphp/faker(https://fakerphp.org/)は、氏名・住所・メール・日付などの擬似データを生成するPHPライブラリ。旧 fzaninotto/faker の後継としてコミュニティがメンテナンスしており、Laravel をはじめ多くの環境で標準的に使われている。
本記事では、インストールから基本的な使い方、シーダー・ファクトリとの組み合わせ、unique() / optional() などの実用的な修飾子、再現性の確保までをハンズオン形式でまとめる。
環境
- PHP 8.1 以上
- Composer
- fakerphp/faker(本記事執筆時点の最新系)
- Laravel 10 以降(シーダー・ファクトリ例で使用)
発生した問題
ダミーデータ整備でよくある困りごとは次のあたりだ。
- 手動でテストデータを作っており、量を増やすのが面倒
- 本番データをコピーして開発環境に流用し、個人情報が混入する
- テストが実行ごとに違うデータを使い、失敗の再現ができない
- 日本語環境なのに英語の名前・住所になってしまう
原因
これらは「ダミーデータ生成を仕組み化していない」ことに起因する。生成ロジックを手続き的に書き散らすと、量・ロケール・再現性のコントロールがすべて個別対応になってしまう。Faker を介して生成ルールを一箇所に寄せることで解決できる。
対応方法
インストール
開発・テスト専用なので --dev で入れる。
composer require --dev fakerphp/faker
基本的な使い方
Factory::create() でジェネレータを生成し、プロパティアクセスでデータを得る。
<?php require 'vendor/autoload.php'; $faker = \Faker\Factory::create(); echo $faker->name; // "John Doe" echo $faker->email; // "jdoe@example.org" echo $faker->address; // 住所 echo $faker->text(100); // ランダムな文章
日本語ロケール
ロケールを ja_JP で生成すると、日本語の氏名・カナ・住所・電話番号が出る。
$faker = \Faker\Factory::create('ja_JP');
echo $faker->name; // "佐藤 花子"
echo $faker->kanaName; // "サトウ ハナコ"
echo $faker->company; // "株式会社〇〇"
echo $faker->prefecture; // "東京都"
echo $faker->phoneNumber; // "090-1234-5678"
よく使うフォーマッタ
// 数値
$faker->numberBetween(1, 100); // 範囲指定
$faker->randomNumber(5); // 桁数指定
$faker->randomFloat(2, 0, 1000); // 小数点以下2桁
// 選択
$faker->randomElement(['A', 'B', 'C']); // 1つ選ぶ
$faker->randomElements(['A', 'B', 'C'], 2); // 複数選ぶ
// 日付
$faker->dateTimeBetween('-1 year', 'now'); // 期間内のDateTime
$faker->dateTimeThisMonth();
// 真偽・その他
$faker->boolean(70); // 70%の確率でtrue
$faker->uuid;
$faker->url;
unique() — 重複しない値
メールアドレスのように UNIQUE 制約があるカラムでは unique() を挟む。生成不能になると OverflowException を投げるので母数には注意する。
$faker = \Faker\Factory::create('ja_JP');
$emails = [];
for ($i = 0; $i < 100; $i++) {
$emails[] = $faker->unique()->safeEmail;
}
// すべて重複なし
optional() — ときどきnull
NULL を許容するカラムのテストに使う。デフォルトは50%の確率で null。
$faker->optional()->text; // 50%でnull $faker->optional(0.9)->text; // 10%でnull(0.9の確率で値) $faker->optional(default: '未設定')->text; // nullの代わりに既定値
再現性 — seed()
テストで「同じデータが毎回出る」ようにするには seed を固定する。失敗の再現に効く。
$faker = \Faker\Factory::create('ja_JP');
$faker->seed(1234);
echo $faker->name; // seedが同じなら常に同じ結果
実装例
Laravel のファクトリで使う
Laravel ではモデルファクトリ内で fake() ヘルパ(内部的に Faker)を使う。
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class UserFactory extends Factory
{
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'profile' => fake()->optional()->realText(100),
'created_at' => fake()->dateTimeBetween('-1 year', 'now'),
];
}
// 状態(state)で属性を上書き
public function unverified(): static
{
return $this->state(fn () => ['email_verified_at' => null]);
}
}
ロケールを ja_JP に固定したい場合は config/app.php の faker_locale を設定する。
'faker_locale' => 'ja_JP',
シーダーで一括投入
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
class UserSeeder extends Seeder
{
public function run(): void
{
// 50件作成
User::factory()->count(50)->create();
// 未認証ユーザーを10件
User::factory()->count(10)->unverified()->create();
}
}
php artisan db:seed --class=UserSeeder
素のPHP/PHPUnitで使う
Laravel でなくても同じ。PHPUnit のテストでジェネレータを用意しておくと、フィクスチャ生成がすっきりする。
<?php
use PHPUnit\Framework\TestCase;
class OrderTest extends TestCase
{
private \Faker\Generator $faker;
protected function setUp(): void
{
$this->faker = \Faker\Factory::create('ja_JP');
$this->faker->seed(42); // テストの再現性を担保
}
public function test_合計金額の計算(): void
{
$price = $this->faker->numberBetween(100, 10000);
$quantity = $this->faker->numberBetween(1, 10);
// ... 検証
}
}
カスタムプロバイダで独自データ
ドメイン固有の値(例:自社の商品コード形式)が欲しいときはプロバイダを足せる。
<?php
use Faker\Provider\Base;
class ProductCodeProvider extends Base
{
public function productCode(): string
{
// 例: PRD-XXXX 形式
return 'PRD-' . $this->generator->numerify('####');
}
}
$faker = \Faker\Factory::create('ja_JP');
$faker->addProvider(new ProductCodeProvider($faker));
echo $faker->productCode(); // "PRD-0472"
確認方法
php artisan db:seed実行後、対象テーブルのレコード件数と内容を確認するunique()を使った箇所で UNIQUE 制約違反が出ないことを確認するseed()を固定したテストを2回実行し、同じ値が得られることを確認する- ロケールを
ja_JPにして、氏名・住所が日本語になっていることを確認する
注意点
- 本番環境でシーダーを流さない。テスト・開発用のデータ生成に限定する
unique()は母数が尽きるとOverflowExceptionを投げる。狭い範囲 × 大量生成を避けるrealText()は実在の文章片を組み替えるため、短すぎる長さ指定だと失敗することがある- 生成データはあくまで擬似。実在の個人を指す可能性はゼロではないので、公開物にそのまま貼らない
- Laravel 旧バージョンでは
$this->faker、新しめではfake()ヘルパが推奨。プロジェクトの慣習に合わせる
まとめ
fakerphp/faker を使うと、ダミーデータ生成を「仕組み」に落とし込める。
Factory::create('ja_JP')で日本語データunique()/optional()で制約・NULL を再現seed()でテストの再現性を確保- Laravel ではファクトリ+シーダーで一括投入
手作業のテストデータ整備や本番データ流用をやめ、Faker に寄せることで、個人情報混入のリスクも減らせる。まずは composer require --dev fakerphp/faker から試してほしい。
