찾다

 >  Q&A  >  본문

Laravel의 스키마를 테스트하기 위해 데이터베이스 마이그레이션

<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粉722409996P粉722409996484일 전510

모든 응답(2)나는 대답할 것이다

  • P粉952365143

    P粉9523651432023-08-27 15:05:56

    테스트 중에는 스키마 덤프 파일을 사용하여 메모리 내 데이터베이스를 작동할 수 없는 것 같습니다

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

    이것을 시도해 볼 수 있습니다

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

    최후의 수단으로만 시도해 보세요. 개인적으로 테스트 환경에서 마이그레이션하는 것을 권장합니다. 이 방법을 채택하는 경우 테스트 환경에서도 마이그레이션 확인을 추가해야 합니다.

    회신하다
    0
  • P粉821274260

    P粉8212742602023-08-27 12:58:12

    드디어 알아냈습니다.

    문제 원인

    문제는 테스트 환경이 제대로 설정되지 않았다는 점입니다. 정확한 원인은 찾지 못했지만, 덤프 파일을 찾아 로딩할 수 있도록 테스트 환경을 설정하는 방법을 알아냈습니다.

    오류를 어떻게 추적하나요

    해결책을 찾기 위해 제가 취한 단계를 설명합니다.

    In database.php 일반 데이터베이스 대신 테스트 데이터베이스를 복사했습니다
    • In database.php 기본 데이터베이스 연결이 있습니다:
    으아악

    그리고 연결 테스트

    으아악
    • 명령줄에서 동일한 결과가 나오는지 확인하기 위해 testing连接数据复制到一个新的mysql연결하겠습니다
    • 이제 파일은 다음과 같습니다
    으아악
    • 콘솔에서 php artisan:migrate
    • 를 실행했습니다.
    • 데이터베이스 덤프 파일을 찾아서 로드했습니다
    • 그래서 일반적인 경우에는 덤프 파일을 찾았지만 테스트 케이스에서는 찾지 못했습니다
    • 몇 가지 조사 끝에 phpunit.xml에서 테스트 환경의 설정을 변경했는데, 이제 설명하겠습니다
    파일phpunit.xml

    phpunit.xml다음과 같습니다(전체 파일은 여기에 표시되지 않음):

    으아악
    • 그러면 테스트 데이터베이스 연결이 단위 테스트로 정의된 것을 볼 수 있습니다
    • 웹에서 테스트를 위해 전체 연결을 변경하는 대신 데이터베이스 테이블만 설정하라는 조언을 찾았습니다. 더 쉽기 때문입니다.
    • 이런 걸 시도해서 phpunit.xml
    • 가 되었습니다.
    으아악
    • database.php中删除了测试连接,并从.env에서 테스트 연결을 제거하고 .env 파일에서 관련 사용되지 않는 변수를 제거했습니다
    • 이 문제가 해결되었습니다. 이제 덤프 파일도 테스트에 로드됩니다
    결론

    Laravel이 덤프 파일을 로드하지 않는 실제 원인은 찾지 못했지만 테스트 목적으로 완전히 새로운 SQL 연결을 정의하는 대신 테스트를 위해 데이터베이스 이름을 변경하는 방법을 찾았습니다. 이로 인해 문제가 해결되었으며 이제 테스트 중에 데이터베이스 덤프 파일이 로드됩니다.

    회신하다
    0
  • 취소회신하다