データベースを移行してLaravelのスキーマをテストする
P粉722409996
P粉722409996 2023-08-26 17:09:54
0
2
503
<p><h1>问题</h1> <ul> <li>我正在使用 Laravel <code>8.83.23</code></li> <li>我有来自压缩迁移的模式转储文件,位于 <code>database\schema\mysql-schema.dump</code></li> <li>测试运行在测试数据库上,就像在 <code>database.php</code> 中一样</li> </ul> <pre class="brush:php;toolbar:false;">'testing' => [ 'driver' => 'mysql', 'host' => env('DB_TEST_HOST', '127.0.0.1'), 'port' => env('DB_TEST_PORT', '3306'), 'database' => env('DB_TEST_DATABASE', 'forge'), 'username' => env('DB_TEST_USERNAME', 'forge'), 'password' => env('DB_TEST_PASSWORD', ''), ],</pre> <ul> <li>在我压缩迁移之前,我的测试用例只使用了 <code>DatabaseMigrations</code> trait,并且测试数据库每次都会被重新创建,一切正常,以下是一个测试类的示例:</li> </ul> <pre class="brush:php;toolbar:false;">class SystemControllerTest extends TestCase { use WithFaker; use DatabaseMigrations; /** * @var User */ private $user; public function setUp(): void { parent::setUp(); //创建角色和数据 $this->seed(RoleAndPermissionSeeder::class); ... 等等</pre> <ul> <li>迁移被找到并执行,重新创建了数据库</li> <li>然后,我压缩了迁移,所以所有的迁移都被删除了,我得到了 <code>database\schema\mysql-schema.dump</code></li> <li><code>php artisan migrate</code> 通过命令行按预期工作,从转储文件中创建完整的数据库模式(它找到了它)</li> <li>然而,测试不再工作,因为出现了一个错误</li> </ul> <pre class="brush:php;toolbar:false;">SQLSTATE[42S02]: Base table or view not found: 1146 Table 'cinema_test.roles' doesn't exist (SQL: delete from `roles`)</pre> <ul> <li>当我在测试运行后检查 sql 测试数据库时,它是空的(只有表 <code>migrations</code> 被创建,而且是空的)</li> <li>即使在测试的设置中调用 <code>artisan migrate</code>,这个错误仍然存在:</li> </ul> <pre class="brush:php;toolbar:false;">public function setUp(): void { parent::setUp(); Artisan::call('migrate', array( '--database' => 'testing', '--force' => true)); //它在这里崩溃 $this->seed(RoleAndPermissionSeeder::class);</pre> <ul> <li><code>RoleAndPermissionSeeder</code> 只操作不存在的 sql 表,因此出现错误</li> <li>我甚至尝试了 <code>DatabaseMigrations</code>、<code>DatabaseTransactions</code> 和 <code>RefreshDatabase</code> traits,但都没有成功</li> <li>我如何填充数据库数据?我无法读取 <code>Artisan::call('migrate')</code> 命令的输出,所以我不知道那里发生了什么</li> <li><code>Artisan::call('migrate')</code> 的返回代码是 <code>0</code></li> <li>我是否可能遗漏了一些设置?</li> </ul></p>
P粉722409996
P粉722409996

全員に返信(2)
P粉952365143

テスト中にスキーマ ダンプ ファイルを使用してメモリ内データベースを操作することはできないようです

https://laravel.com/docs/9.x/migrations#squashing-migrations

これを試すことができます

DB::unprepared(file_get_contents("path/file.sql"));

あくまで最終手段として試してください。個人的にはテスト環境で移行することをお勧めします。この方法を採用する場合は、テスト環境でも移行のチェックを追加する必要があります。

いいねを押す +0
P粉821274260

やっと分かりました。

問題の原因

問題は、テスト環境の設定が正しくないことにあります。正確な原因は見つかりませんでしたが、ダンプ ファイルが見つかってロードされるようにテスト環境をセットアップする方法はわかりました。

エラーを追跡するにはどうすればよいですか

これは、解決策を見つけるために私が行った手順を説明します。

database.php では、通常のデータベースの代わりにテスト データベースをコピーしました
  • database.php には、メインのデータベース接続があります:
リーリー

およびテスト接続

リーリー
  • コマンドラインで同じ結果が得られるかどうかを確認するために、testing 接続データを新しい mysql 接続にコピーしました。
  • つまり、ファイルは次のようになります
  • リーリー
    コンソールで、
  • phpArtisan:Migrateを実行しました。
  • データベース ダンプ ファイルが見つかり、ロードされました
  • つまり、通常の場合はダンプ ファイルが見つかりますが、テスト ケースでは
  • not found
  • 調べた結果、
  • phpunit.xml のテスト環境の設定を変更しました。これから説明します
ファイル
phpunit.xml

phpunit.xml は次のようになります (完全なファイルはここには示されていません): リーリー

    つまり、テスト データベース接続が単体テストとして定義されていることがわかります
  • Web 上で、テストのために接続全体を変更するのではなく、データベース テーブルをセットアップするだけの方が簡単であるというアドバイスを見つけました。
  • 次のようなことを試したので、
  • phpunit.xml になりました
  • リーリー
    テスト接続を
  • database.php から削除し、関連する廃止された変数を .env ファイルから削除しました
  • これで問題は解決しました。ダンプ ファイルもテストにロードされるようになりました
  • ###結論は###
Laravel がダンプ ファイルのロードに失敗する実際の原因は見つかりませんでしたが、テスト目的で完全に新しい SQL 接続を定義するのではなく、テスト専用にデータベース名を変更するという回避策を見つけました。これにより問題が修正され、テスト中にデータベース ダンプ ファイルが読み込まれるようになりました。
いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート