H.Iidaをフォローする

【Laravel】 ダミーデータを自動生成しよう ~前編~

バックエンド

初めまして、エンジニアのh.iidaです。
今回、Laravelを使用した案件でダミーデータを自動生成するプログラムが必要だったため、
FactoryやSeederなどの使い方を一から学び直しました。
内容の整理も兼ねて、使用方法や工夫した点をご紹介したいと思います。
※Laravel 6 を使用しています。

なぜダミーデータ生成が必要?

業務フローが複雑で、手作業で全パターンをテストするのが難しい…
テストしたい部分まで到達するために、途中のデータ入力に時間がかかってしまう…

社内でのそんな悩みを解決するため、一括で全パターンのデータを生成してしまおう!
というのがきっかけです。
もちろん自動生成のためのプログラムを作るためにもある程度時間はかかりますが、
全体で見ればコストは削減できたと思います。

Factoryを使ってみよう

いろいろなパターンのデータを作成するにあたって、まずはその”工場”となるFactoryについて知る必要があります。
初期状態で含まれているdatabase/factories/UserFactory.phpを見てみます。

use Faker\Generator as Faker;
use Illuminate\Support\Str;

$factory->define(User::class, function (Faker $faker) {
    return [
        'name'              => $faker->name,
        'email'             => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password'          => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token'    => Str::random(10),
    ];
});

Factoryとは?

  • Userモデルに必要なデータを作成する際のルールを定義
  • Fakerが標準装備されておりランダムなデータを作成できる
    ※Fakerについて詳しくは公式Github参照

実際にデータを作成してみる

Tinkerや実際のコードに埋め込んで以下を実行してみましょう。

すると以下の様なデータが作成されます。

App\User {
     name: "渡辺 亮介",
     email: "bsakamoto@example.com",
     email_verified_at: "2020-07-14 12:00:00",
     api_token: "HUnFCEURe4t53aMbPtPJc2CTPFj9Cnt1KAyjA5Fo161t80sgjmBxLv6vWdsEqwA28QVJilQWo6P8TVtS",
     updated_at: "2020-07-14 12:00:00",
     created_at: "2020-07-14 12:00:00",
     id: 1,
}

たった1行の実行でダミーデータを作成することができました。

任意の値でデータ作成

Factoryで設定した値はダミーデータ作成時のデフォルトの値になりますが、
各項目を手動で設定したい場合もあります。
その場合、createメソッドを呼ぶ際に配列で値を渡すことでデフォルト値を上書きすることができます。

>>> factory(User::class)->create(['name' => 'テスト 太郎', 'email' => 'test_taro@example.com']);

App\User {
     name: "テスト 太郎",
     email: "test_taro@example.com",
     email_verified_at: "2020-07-14 12:05:00",
     api_token: "HUnFCEURe4t53aMbPtPJc2CTPFj9Cnt1KAyjA5Fo161t80sgjmBxLv6vWdsEqwA28QVJilQWo6P8TVtS",
     updated_at: "2020-07-14 12:05:00",
     created_at: "2020-07-14 12:05:00",
     id: 2,
}

「ステート」を活用する

要件としてユーザを権限で分けたい、ということはよくあります。
Factoryにステートを設定しておくことにより、色々なパターンでダミーデータを作成することができます。

例えば、usersテーブルに”authority”というカラムを追加し、
 ・ 管理者
 ・ 一般
 ・ 閲覧のみ
の3種類の権限を持たせることを考えます。

UserFactoryにはデフォルトの値を設定しておきます。今回は「閲覧のみ」をデフォルトにしました。

$factory->define(User::class, function (Faker $faker) {
    return [
        'name'              => $faker->name,
        'email'             => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password'          => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token'    => Str::random(10),
        'authority'         => 3, // 1:管理者、2:一般、3:閲覧のみ
    ];
});

そしてUserFactoryにステートの定義を追加します。
管理者と一般のステートを以下のように定義します。

$factory->state(User::class, 'admin', [
    'authority' => 1, // 1:管理者
]);
$factory->state(User::class, 'general', [
    'authority' => 2, // 2:一般
]);

すると、以下のようにステートを指定してデータを作成することが出来るようになります。

>>> factory(User::class)->create();                    // 閲覧のみのユーザを作成(デフォルト)
>>> factory(User::class)->states('admin')->create();   // 管理者を作成
>>> factory(User::class)->states('general')->create(); // 一般ユーザを作成

【応用】
>>> factory(User::class, 10)->states('general')->create(); // 一般ユーザを10人作成

まとめ

今回はFactoryの利用方法をまとめました。ステートを活用することで、様々なパターンのダミーデータが作れるようになります。後編ではもう少し詳しいところを掘り下げるのと、Seederを用いた初期投入データの作成方法などもまとめてみたいと思います。