【Laravel】ファクトリーとは:Factoryの使い方やテストデータの生成

2024.01.07 /

【Laravel】ファクトリーとは:Factoryの使い方やテストデータの生成

記事ではLaravelにおける、ファクトリー(Factory)について詳しく解説していきます。

ファクトリーとは大量のテストデータや初期データを簡単に生成できる機能です。手動でテストデータを入力する手間を省くだけでなく、実際のデータに近い状態でテストデータを自動生成できます。

本記事を通して、ファクトリーについて理解を深めてください。

ファクトリー(Factory)とは

ファクトリー(Factory)とはテストデータやダミーデータ、シードデータを簡単に生成できる機能です。

POINT

シーダーでは一つずつレコードを記入していましたが、ファクトリーでは簡単に大量のテストデータを生成できます

Webアプリケーションでは必ずテストを行い、問題がないことを確認してから実際の運用という流れになります。テスト時には多くのテストデータが登録されていることが望ましいです。

手動でテストデータを入れるのは時間がかかるため、Laravelに備わっているファクトリーを利用するのが通常です。

シーダーとは

ファクトリーと共に利用される機能にシーダー(Seeder)があります。シーダーとはデータベースのテーブルにデータの初期値を登録、テスト用のダミーデータを登録する機能です。

シーダーはファクトリーと異なり、一つずつレコードを指定します。シーダーについては以下記事をご参照ください。

ファクトリーファイルの作成

ファクトリー機能を利用するためのファクトリーファイルはartisanコマンドで生成することができます。以下構文に沿ってコマンドを実行します。

構文

php artisan make:factory モデル名Factory

例えばBookingモデルのファクトリーを作成する場合は以下コマンドを実行します。

php artisan make:factory BookingFactory

上記コマンドを実行すると「database/factories」内にBookingFactory.phpというファクトリーファイルが作成されます。

Laravel:factoryのファイル

ファイルの中身は以下のようになっています。

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Booking>
 */
class BookingFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            //
        ];
    }
}

Factoryクラスは「Database\Factories」名前空間に配置され、
「Illuminate\Database\Eloquent\Factories\Factory」を継承していることがわかります。

ファクトリーファイルを生成したら、次はFactoryクラスにどのようなデータを生成するかを定義します。

注意点

ここではすでにモデルが作成されており、かつマイグレーションが実行されてテーブルが作成されていることを前提としています。モデル作成やマイグレーションの実行がまだしていない方は以下記事を参考にしてください。

ファクトリーのデータ定義

作成したファクトリーファイル(ここではBookingFactory.php)を開いて、Factoryクラスにデータを定義していきます。

データ定義はクラス内のdefinitionメソッド内に記入します。

public function definition(): array
{
    return [
        // ここにデータ定義を記入する
    ];
}

例えばdefinitionメソッドへのデータ定義は以下のように記述します。

public function definition(): array
{
    return [
        'name'=>fake()->name(),
        'address'=>fake()->address(),
        'email'=>fake()->email(),
        'title'=>fake()->text(30),
        'body'=>fake()->text(100),
    ];
}
  • nameフィールドにはランダム生成された人名が入る
  • addressフィールドにはランダム生成された住所が入る
  • emailフィールドにはランダム生成されたメールアドレスが入る
  • titleフィールドにはランダム生成された30字以内のテキストが入る
  • bodyフィールドにはランダム生成された100字以内のテキストが入る

fake()ではFakerライブラリを利用しており、人名や住所、メールアドレス、テキストなどをランダム生成します。Fakerでデータのランダム生成で利用できるメソッドは以下の通りです。

データタイプ 入るデータ
text() テキスト(日本語非対応)
realText() テキスト(日本語対応)
word() 単語
paragraph() 複数の文章
address() 住所
country()
postcode() 郵便番号
prefecture() 都道府県
city()
company() 会社名
phoneNumber() 電話番号
email() メールアドレス
name() 人名
lastName()
firstName()
numberBetween($min=〇, $max=〇) 指定した範囲内の数値
date() 年月日
dateTime() 年月日 時分秒
year()
month()
dayOfMonth()
time() 時分秒

もしテーブル(モデル)にリレーションがある場合、リレーションについても考慮する必要があります。例えばBookingモデルがUserモデルにリレーションがある場合はファクトリーのデータ定義にUserモデルへのリレーションを定義する必要があります。

public function definition(): array
{
    return [
        'name'=>fake()->name(),
        'address'=>fake()->address(),
        'email'=>fake()->email(),
        'title'=>fake()->text(30),
        'body'=>fake()->text(100),
        'user_id'=>\App\Models\User::factory(), // 追記
    ];
}

追記コードによりファクトリー実行時に新しいuserを作成され、そのuserのidがuser_idに入ります。

設定ファイル「config/app.php」内の「faker_locale」を日本語設定しておくと、日本語対応のデータタイプでは日本語のデータを入れます。

// config/app.php
'faker_locale' => 'ja_JP',

ファクトリーではFakerライブラリを利用することでリアルなテストデータを作成できるので積極的に利用してください。

ファクトリーの実行

ファクトリーファイルにデータ定義できたら、「database/seeders/DatabaseSeeder.php」を開いてrunメソッド内にファクトリーを実行するコードを記述します。

public function run(): void
{
    \App\Models\Booking::factory(10)->create(); //追記
}

追記したコードではファクトリーを使ってテストデータを10個作成します。

またファクトリーに関連するモデルクラスに以下コードが記述されていることを確認してください。記述されてなければ記述してください。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Booking extends Model
{
    use HasFactory; // この記述が必要
}

以下コマンドでDatabaseSeeder.phpのrunメソッドが実行されます。

php artisan db:seed

上記コマンドを実行後にデータベースを確認すると、テストデータが追加されていることが確認できます。

POINT

DatabaseSeeder.phpはシーダーで利用されるファイルですが、今回のようにファクトリーでも利用されます

またはDatabaseSeeder.phpに記述するのではなく、作成したシーダーファイルのrunメソッド内に記述してシーダーを実行しても同様の結果が得られます。

php artisan make:seeder BookingSeeder
// database/seeders/BookingSeeder.php
public function run(): void
{
    \App\Models\Booking::factory(10)->create(); //追記
}