Blank?=False

ゆるゆる仕事したいフリーランスエンジニアの記事

【PHPUnit】RefreshDatabaseについて

LaravelのPHPUnit で「おまじない」として毎回入れているuse RefreshDatabase、 これはどのような動きをするか理解するため調べました。

readouble.com

RefleshDatabaseについて

テストケースの先頭にこんな感じで`use RefreshDatabase;'を記載している方は多いと思います。

この機能ですが、 テスト実行毎にデータベースを初期化するというものです。

RefreshDatabaseを使わない場合

カテゴリーというモデルがあったとして,それをテストメソッド内で5個のインスタンスを作る動きをします。

<?php
class sample_Test extends TestCase
{
    /**
     * サンプルテスト
     */
    public function test_Sample(): void
    {

        Category::factory(5)->create()->each( function ($cat){
            printf("ID: {$cat->id}\n");
        } );

        $this->assertTrue(true);
    }
}

1回目の実行結果

ID: 1
ID: 2
ID: 3
ID: 4
ID: 5

2回目の実行結果

ID: 6
ID: 7
ID: 8
ID: 9
ID: 10

説明

2回目の実行結果は前回5個作っているので、6から再度作られます。 つまり、テスト実行毎に処理内容が変わってしまうわけです。

RefreshDatabaseを使う場合

use RefreshDatabaseをテストケースクラス先頭に追加しました。

<?php
class sample_Test extends TestCase
{
    use RefreshDatabase;   //追加!

    /**
     * サンプルテスト
     */
    public function test_Sample(): void
    {

        Category::factory(5)->create()->each( function ($cat){
            printf("ID: {$cat->id}\n");
        } );

        $this->assertTrue(true);
    }
}

1回目の実行結果

ID: 1
ID: 2
ID: 3
ID: 4
ID: 5

2回目の実行結果

ID: 1
ID: 2
ID: 3
ID: 4
ID: 5

説明

2回目の実行結果は前回5個作っているので、6から再度作られます。 つまり、テスト実行毎に処理内容が変わってしまうわけです。

まとめ

テストケースは毎回不変であるべき(じゃないとテストの意味がない)ので、 DBを使用するテストならuse RefreshDatabaseを使用して毎回DBを空にしてテストを行うことが最低条件になります。

こういう「毎回入れるもの」は入門本ではよくおまじないと言われますが、 実際に業務に使うなら、しっかりどういった動きをするものか把握してから使うべきと考えています。