Laravel Behat 数据库连接
Laravel Behat DB connection
我一直在与 behat 和 laravel 一起工作时遇到问题。
我用 Laravel 配置了 Behat。我有这个简单的场景:
Scenario: Login as an admin
Given I add an admin to the db
When I login as an admin
Then I should be in the welcome page
在 FeatureContext 中 Class 我使用工厂将管理员用户插入数据库。
如果我不使用浏览器,一切正常。但是,当我启动 selenium 服务器并将 @javascript 标记添加到场景时,测试 运行 正常,浏览器启动正常,但登录过程失败,因为数据库中没有用户.是的,具有我刚刚在第一步中添加的相同凭据的同一用户。我还通过在执行登录之前查询数据库来检查用户,并且用户在那里。
顺便说一句,我只有一个连接,我检查了三次。
那么,这里发生了什么?有什么想法吗?
谢谢。
我想我解决了这个问题,或者至少我找到了解决方法。
由于某些原因,当使用 behat 和 selenium 启动浏览器时,DB::beginTransaction() 和 DB::rollback() 无法正常工作。经过一段时间的研究,我想出了下一个解决方案。显然,因为我正在使用 vagrant 虚拟机启动我的应用程序,当浏览器被 Selenium 启动时,它会启动一个新会话。此外,它使用了 laravel 的另一个实例,与 behat 正在使用的实例不同。这意味着我试图用 behat 实现的事务永远不会影响应用程序在浏览器中使用的同一个数据库。此外,我为我的测试 (.env.testing) 使用了不同的 .env 配置文件,我在其中定义了 laravel 需要用于测试环境的所有参数,但无法告诉应用程序通过 behat 和 selenium 启动的浏览器并更改为测试环境,应用程序将使用常规环境配置文件,在我的例子中是 .env(开发)。
请看下面我想出的代码:
```
/**
* @javascript
* @BeforeFeature
*/
public static function before(BeforeFeatureScope $scope)
{
putenv('APP_ENV=local');
$tableNames = Schema::getConnection()->getDoctrineSchemaManager()->listTableNames();
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
foreach ($tableNames as $name) {
//if you don't want to truncate migrations
if ($name == 'migrations') {
continue;
}
DB::table($name)->delete();
}
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
Artisan::call('migrate');
try {
Artisan::call('db:seed');
} catch (Exception $e) {
dump('seeder failed');
}
}
/**
* @javascript
* @AfterFeature
*/
public static function after(AfterFeatureScope $scope)
{
putenv('APP_ENV=local');
Artisan::call('migrate:rollback');
$tableNames = Schema::getConnection()->getDoctrineSchemaManager()->listTableNames();
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
foreach ($tableNames as $name) {
//if you don't want to truncate migrations
if ($name == 'migrations') {
continue;
}
DB::table($name)->delete();
//Schema::dropIfExists($name);
}
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}
```
告诉 vagrant 机器内的应用程序使用哪个环境的解决方案可以是基于 url 的 vagrant 机器内的 Web 服务器中的配置,加载具有不同环境的应用程序。例如:
标准 url: https://localhost:8000/auth/login
测试 url: https://localhost:8000/test/auth/login
在这种情况下,所有应用程序 url 都将包含 test
。
希望这对以后的人有所帮助。如果有人有更好的方法,欢迎尝试。
干杯
我一直在与 behat 和 laravel 一起工作时遇到问题。 我用 Laravel 配置了 Behat。我有这个简单的场景:
Scenario: Login as an admin
Given I add an admin to the db
When I login as an admin
Then I should be in the welcome page
在 FeatureContext 中 Class 我使用工厂将管理员用户插入数据库。
如果我不使用浏览器,一切正常。但是,当我启动 selenium 服务器并将 @javascript 标记添加到场景时,测试 运行 正常,浏览器启动正常,但登录过程失败,因为数据库中没有用户.是的,具有我刚刚在第一步中添加的相同凭据的同一用户。我还通过在执行登录之前查询数据库来检查用户,并且用户在那里。
顺便说一句,我只有一个连接,我检查了三次。
那么,这里发生了什么?有什么想法吗?
谢谢。
我想我解决了这个问题,或者至少我找到了解决方法。
由于某些原因,当使用 behat 和 selenium 启动浏览器时,DB::beginTransaction() 和 DB::rollback() 无法正常工作。经过一段时间的研究,我想出了下一个解决方案。显然,因为我正在使用 vagrant 虚拟机启动我的应用程序,当浏览器被 Selenium 启动时,它会启动一个新会话。此外,它使用了 laravel 的另一个实例,与 behat 正在使用的实例不同。这意味着我试图用 behat 实现的事务永远不会影响应用程序在浏览器中使用的同一个数据库。此外,我为我的测试 (.env.testing) 使用了不同的 .env 配置文件,我在其中定义了 laravel 需要用于测试环境的所有参数,但无法告诉应用程序通过 behat 和 selenium 启动的浏览器并更改为测试环境,应用程序将使用常规环境配置文件,在我的例子中是 .env(开发)。
请看下面我想出的代码:
```
/**
* @javascript
* @BeforeFeature
*/
public static function before(BeforeFeatureScope $scope)
{
putenv('APP_ENV=local');
$tableNames = Schema::getConnection()->getDoctrineSchemaManager()->listTableNames();
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
foreach ($tableNames as $name) {
//if you don't want to truncate migrations
if ($name == 'migrations') {
continue;
}
DB::table($name)->delete();
}
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
Artisan::call('migrate');
try {
Artisan::call('db:seed');
} catch (Exception $e) {
dump('seeder failed');
}
}
/**
* @javascript
* @AfterFeature
*/
public static function after(AfterFeatureScope $scope)
{
putenv('APP_ENV=local');
Artisan::call('migrate:rollback');
$tableNames = Schema::getConnection()->getDoctrineSchemaManager()->listTableNames();
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
foreach ($tableNames as $name) {
//if you don't want to truncate migrations
if ($name == 'migrations') {
continue;
}
DB::table($name)->delete();
//Schema::dropIfExists($name);
}
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}
```
告诉 vagrant 机器内的应用程序使用哪个环境的解决方案可以是基于 url 的 vagrant 机器内的 Web 服务器中的配置,加载具有不同环境的应用程序。例如:
标准 url: https://localhost:8000/auth/login
测试 url: https://localhost:8000/test/auth/login
在这种情况下,所有应用程序 url 都将包含 test
。
希望这对以后的人有所帮助。如果有人有更好的方法,欢迎尝试。
干杯