Laravel入門 Laravelでのテストデータ作成方法(第9回)

2021-01-01
6 min read

Laravel でテストデータを用意する方法を学びます。学ぶのは、シーダーとフェイカーを利用してのテストデータ作成になります。

データ作成

テストデータを準備したいときに便利な機能が Laravel にあります。 シーダーとフェイカーです。

  • シーダー
  • モデルファクトリでのFaker

シーダークラスにて作成

シーダーを利用したテストデータ作成方法を見ていきましょう。
artisanコマンドでシーダークラスを作成します。

下記のコマンドで、TasksTableSeederが、/database/seeds/以下に作成されます。

$ php artisan make:seeder TasksTableSeeder

次にシーダークラスのrunメソッドを下記のように編集します。

public function run()
{

          DB::table('tasks')->insert([
              [
                       'title' => 'fortniteで櫓の建築'
                      , 'status' => 1
                      , 'description' => '秒で3段の櫓を作る'
              ],
              [
                       'title' => 'fortniteでチャージショットガンの撃ち方'
                      , 'status' => 1
                      , 'description' => 'チャージショットガンを撃った後に壁を作る'
              ]
          ]);
}

DB::table('tasks')->insert()で、テーブルのフィールドをキーとした連想配列を渡します。この場合は 2 レコードになります。

データをテーブルに書き込むには、database/seeds/DatabaseSeeder.phpにて、TasksTableSeedercallメソッドで呼び出します。

// database/seeds/DatabaseSeeder.php
public function run()
{
    $this->call(TasksTableSeeder::class);
}

実行は下記コマンドになります。

$ php artisan db:seed

複数のシーダークラスがあり、特定のシーダークラスだけを実行したい場合は、-class オプションで下記のように実行します。

$ php artisan db:seed --class=TasksTableSeeder

ブラウザからアクセスしてください。追加したデータが表示されます。

http://localhost/

ToDo一覧画面Seederデータ追加

シーダーの公式ドキュメントの日本語訳は下記になります。 https://readouble.com/laravel/7.x/ja/seeding.html

フェイカーにて作成

シーダーでは少量の特定のデータを作成するには十分なのですが、大量のデータとなると苦しいです。

そんな場合は、モデルファクトリを利用してテストデータを作ります。
https://readouble.com/laravel/7.x/ja/seeding.html

モデルファクトリは Laravel8 で大幅な変更が行われたため Laravel8 以上では以下の方法では動作しないのでご注意ください。

さっそく、作成方法を見ていきましょう。

モデルファクトリの生成

artisanコマンドでモデルファクトリを作成します。
下記のコマンドで、TaskFactoryが、/database/factories/以下に作成されます。

$ php artisan make:factory TaskFactory --model=Task

作成されたTaskFactoryを見てみましょう

// database/factories/TaskFactory.php
<?php

use App\Task;
use Faker\Generator as Faker;

$factory->define(Task::class, function (Faker $faker) {
    return [
        //
    ];
});

次に生成されたモデルファクトリのreturnの戻り値の部分に各フィールドに対してfakerの記述をします。

$factory->define(Task::class, function (Faker $faker) {
    return [
         'title' => $faker->word
        ,'status' => $faker->numberBetween(1,4)
        ,'description' =>  $faker->realText(200)
        ,'created_at' => $faker->dateTimeThisMonth
        ,'updated_at' => $faker->dateTimeThisMonth
    ];
});

fakereは、ランダムでそれぞれの値を用意してくれます。 上記では、下記のメソッドを利用しています。

  • word
  • numberBetween
  • realText
  • dateTimeThisMonth

これら以外にもさまざまなメソッドがあります。
https://github.com/fzaninotto/Faker

フェイクデータの定義ができたので、データ生成の記述をします。

$ php artisan make:seeder TasksTableFakeSeeder

シーダークラスの生成を行い、2 行目に、use App\Task;を宣言して、run メソッドに、 factory(Task::class,10)->create();を記述します。

use Illuminate\Database\Seeder;
use App\Task;

class TasksTableFakeSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
         factory(Task::class,10)->create();
    }
}

上記の factory メソッドの引数は、生成するクラス名と件数になります。 件数を 100 とすれば、100 件のフェイクデータが作成されます。

database/seeds/DatabaseSeeder.phpの記述を下記のように変更します。

public function run()
{
    $this->call(TasksTableFakeSeeder::class);
}

実行

実行は下記コマンドです。

$ php artisan db:seed

http://localhost/

ToDo一覧画面Seederデータ追加

今度は、10 件のデータが追加されて表示されましたよね。

フェイカーの日本語対応

フェイカーで追加したデータが英語になっています。そこで、フェイカーを日本語対応させます。

config/app.phpfaker_locale'en_US'から'ja_JP'に変更します。

'faker_locale' => 'ja_JP',

設定ファイルを変更した場合は、設定ファイルのキャッシュをクリアします。

$ php artisan config:clear

データを作成します。

$ php artisan db:seed

ブラウザの再表示をしてください。

http://localhost/

データは追加されましたが、日本語は表示されていません。

一度、psqlでテーブルを確認してみます。 新しくターミナルを開きます。 Ctrl + Shift + @ で 新しいターミナルを開くことができます。

developer@Ryzen:/var/www/html/todo$ psql -d todo
psql (12.5 (Ubuntu 12.5-0ubuntu0.20.04.1))
Type "help" for help.
todo=>
todo=> \x
todo=> select * from tasks;

faker日本語確認

descriptionの部分が日本語になっていることが確認できます。 残念ながら、Fakerのメソッドのtitleは英語のままです。realText,nameなどは日本語対応されているのですが、word にように日本語対応されていないものもあります。

初期データの設定

テーブルに登録済みのデータからシーダーを作成します。 ツールを使うことで、Seeder を作成できます。 composerにてツールを導入します。

$ composer require orangehill/iseed:"2.6.4"

Seederをテーブルから作成します。 しかし、自動で生成されるSeederファイルの名前が、すでに作成したものと重複してしまうためsuffixをつけます。

$ php artisan iseed tasks --classnamesuffix=Init 

上記コマンドで、todo/database/seeds/の配下に、TasksTableInitSeeder.php が作成されます。

中身を確認してください。そして、最初の4件のデータだけ残して後は削除して保存します。 また、idフィールドはInsert時に自動で振られるようにするためコメントアウトします。

    public function run()
    {
        

        \DB::table('tasks')->delete();
        
        \DB::table('tasks')->insert(array (
            0 => 
            array (
                //'id' => 1,
                'title' => 'bitcoinの半減期を調べる',
                'status' => 2,
                'description' => 'bitcoinの半減期と価格の相関性を調べる',
                'created_at' => NULL,
                'updated_at' => NULL,
            ),
            1 => 
            array (
                //'id' => 2,
                'title' => 'サンフランシスコ旅行',
                'status' => 2,
                'description' => 'サンノゼ空港からパロ・アルトへの行き方を調べる',
                'created_at' => NULL,
                'updated_at' => NULL,
            ),
            2 => 
            array (
                //'id' => 3,
                'title' => 'アクアパッツァ',
                'status' => 3,
                'description' => '再来週の食事会のためにアクアパッツァの作り方を学ぶ',
                'created_at' => NULL,
                'updated_at' => NULL,
            ),
            3 => 
            array (
                //'id' => 4,
                'title' => 'サンフランシスコ行きの航空券',
                'status' => 4,
                'description' => '羽田からサンノゼ空港行きのチケットを予約',
                'created_at' => NULL,
                'updated_at' => NULL,
            ),
        ));
        
        
    }

そして、todo/database/seeds/DatabaseSeeder.php の run() メソッドを下記のようにコメントアウトします。

    public function run()
    {
       //$this->call(TasksTableSeeder::class);
       //$this->call(TasksTableFakeSeeder::class);
       $this->call(TasksTableInitSeeder::class);

    }

下記のコマンドでデータベースを初期化します。

$ php artisan migrate:refresh --seed

ブラウザの再表示をしてください。

http://localhost/

表示されるデータが4件のみになりましたか?