[英]Laravel tests database migration from schema
8.83.23
database\schema\mysql-schema.dump
中有压缩迁移的模式转储database.php
'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', ''),
],
DatabaseMigrations
特征,并且每次都重新创建测试数据库并且一切正常,测试 class 的示例:
class SystemControllerTest extends TestCase
{
use WithFaker;
use DatabaseMigrations;
/**
* @var User
*/
private $user;
public function setUp(): void
{
parent::setUp();
//create roles and data
$this->seed(RoleAndPermissionSeeder::class);
... etc
database\schema\mysql-schema.dump
php artisan migrate
通过命令行按预期工作,从转储创建完整的数据库模式(它找到它)
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'cinema_test.roles' doesn't exist (SQL: delete from `roles`)
migrations
在那里创建,它是空的)artisan migrate
,此错误仍然存在:
public function setUp(): void
{
parent::setUp();
Artisan::call('migrate', array(
'--database' => 'testing',
'--force' => true));
//it crashes here
$this->seed(RoleAndPermissionSeeder::class);
RoleAndPermissionSeeder
仅使用不存在的 sql 表进行操作,因此出现错误DatabaseMigrations
和DatabaseTransactions
和RefreshDatabase
特征,但没有任何成功Artisan::call('migrate')
命令的 output,所以我不知道那里发生了什么Artisan::call('migrate')
的返回码为0
似乎在测试时模式转储不能用于内存数据库
https://laravel.com/docs/9.x/migrations#squashing-migrations
也许可以做这样的事情
DB::unprepared(file_get_contents("path/file.sql"));
只会尝试作为最后的手段,个人想要测试迁移,如果你采用这种方法,你也应该添加一个测试迁移的检查
我终于想通了。
问题在于测试环境的设置不正确。 我还没有找到确切的原因,但我想出了如何设置测试环境以便找到并加载转储。
这描述了我如何找到解决此问题的方法的步骤。
database.php
我复制了测试数据库而不是普通数据库database.php
我有主数据库连接:
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => false,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
和测试连接
'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', ''),
],
testing
连接数据复制到一个新的mysql
连接中,只是为了看看,是否在命令行上我得到相同的结果
'mysql' => [
'url' => env('DATABASE_URL'),
'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', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => false,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
/*'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', ''),
],*/
php artisan:migrate
phpunit.xml
中的测试环境设置,我现在解释一下phpunit.xml
phpunit.xml
如下(此处未显示完整文件):
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="TELESCOPE_ENABLED" value="false"/>
<env name="DB_CONNECTION" value="testing"/>
</php>
</phpunit>
phpunit.xml
变成了 <server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="TELESCOPE_ENABLED" value="false"/>
<env name="DB_DATABASE" value="cinema_test"/>
</php>
</phpunit>
database.php
和.env
文件中的相关过时变量中删除了测试连接虽然我还没有弄清楚 lavavel 没有加载转储文件的真正原因,但我找到了一种解决方法,即只更改用于测试的数据库名称,而不是为测试目的定义全新的 sql 连接。 这解决了这个问题,并且现在在测试期间加载了数据库转储文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.