@suu_

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

PHPunitテストについて、正しい挙動か教えてください。

解決したいこと

PHPunitテストについて、正しい挙動か教えてください。

前提:
ログインに関するテストを5つ作る過程で、始めにsetUpしています。
そして、各テストが終わるごとに、use RefreshDatabase; でリセットをかけるようにしたいです。
※マイグレーションを使用しています。

現状:
setUp()で作られるデータをdump();で確認すると、
1つのデータが出てくるのが正しいと考えていたのですが、
実際は下記のようなnameやemailは変わらず、idが1.2.3....5と増えてデータが5つ返ってきました。
※chatGPTに聞いてみたところ、「use RefreshDatabase; が機能していない」と言われたのですが、
リセットはされている気がします。(dump('Before Creating User:', User::all()->toArray());でデータ作成前の状態は空だったためです。)
5つ返ってくるのは正しいのでしょうか?

※Loginテスト自体はidを使用しないので、エラーにはなっていません。
 他のテストケースではidを使用するので躓いています。

該当するテストコード


namespace Tests\Feature\Auth;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Facades\Log;
use Tests\TestCase;
use App\Models\User;

class LoginTest extends TestCase
{
    use RefreshDatabase;
    /**
     * A basic feature test example.
     *
     * @return void
     */
    public $user;
    protected function setUp(): void
    {
        parent::setUp();
        dump('Before Creating User:', User::all()->toArray());
        $this->user = User::factory()->create([
            'name' => 'テスト',
            'email' => 'test123@example.com',
            'password' => bcrypt('password123'),
        ]);
        dump('After Creating User:', User::all()->toArray());
    }

dumpの結果:


"Before Creating User:"
[]
"After Creating User:"
array:1 [
  0 => array:8 [
    "id" => 1
    "name" => "テスト"
    "email" => "test123@example.com"
    "created_at" => "2025-03-21"
    "updated_at" => "2025-03-21"
  ]
]
."Before Creating User:"
[]
"After Creating User:"
array:1 [
  0 => array:8 [
    "id" => 2
    "name" => "テスト"
    "email" => "test123@example.com"
    "created_at" => "2025-03-21"
    "updated_at" => "2025-03-21"
  ]
] (これが"id" => 5まで続きます)

自分で試したこと

①dump('Before Creating User:', User::all()->toArray()); より、データベースが空になっているのか確認。
②database.php、phpunit.xmlなど設定を確認。

0 likes

1Answer

idが1.2.3....5と増えてデータが5つ返ってきました。

「dumpの結果」が途中までですが、「"After Creating User:"」の後は「array:1」となっているので、返ってきているデータは常に1つではないでしょうか?

おそらくは「idの自動インクリメントがリセットされていない」という点についての質問と解釈して回答します。

※ RefreshDatabaseをはじめとしたデータベースを使ってテストを行う仕組みはLaravelフレームワークが提供するものです。より正確な回答を求めるのでしたら、Laravelのバージョン情報などを記載するのが良いでしょう。

回答

少し調べてみた感じなのですが、おそらく正しい挙動と思われます。
ポイントは3つです。

  1. 最初のテストでmigrate:fresh(テーブルのdropとマイグレーション)が実行される
  2. 2回目以降はトランザクションをロールバックすることでデータをリセットしている
  3. トランザクションのロールバックでは自動インクリメントはリセットされない(ひとまずMySQLの場合は)

よって、そのテストクラスの中で自動インクリメントのIDが増え続けるのは正しい挙動と思われます。

(使用しているDBMSなどによって挙動が異なるかもしれません)

参考

This normally doesn't work when you use RefreshDatabase because the auto-increment doesn't reset between tests.
-- https://github.com/laravel/framework/issues/54079#issuecomment-2571670765

「INSERT のような」ステートメントが完了したかどうか、およびそれを含むトランザクションがロールバックされたかどうかに関係なく、自動インクリメントカラムの値は一度生成されたら、ロールバックできません。
-- https://dev.mysql.com/doc/refman/8.0/ja/innodb-auto-increment-handling.html

2Like

Comments

  1. @suu_

    Questioner

    正しい挙動だったんですね、、
    教えていただきありがとうございます!

Your answer might help someone💌