Laravel Dusk测试异常:SQLite测试库未生效,调用开发库数据
看起来你遇到的问题是Dusk测试用例在测试数据库里创建了用户,但实际浏览器访问应用时,应用还是在读取开发数据库的数据——这是个常见的Dusk坑,因为Dusk是通过真实浏览器访问应用,应用实例的环境和测试用例本身的环境可能没同步上。下面是几个针对性的解决步骤:
Laravel Dusk会在运行测试时自动切换到对应环境的配置文件,你需要创建(或修改).env.dusk.local文件(本地测试环境用这个),确保里面的数据库配置指向你的SQLite测试库:
APP_ENV=testing DB_CONNECTION=sqlite DB_DATABASE=database/testing.sqlite # 替换成你实际的测试SQLite文件路径
划重点:Dusk运行时会自动把你的主.env重命名,换成这个.env.dusk.local,所以应用实例会加载这个文件的配置——一定要确保这里的数据库和测试用例用的是同一个。
你已经用了DatabaseMigrations trait,这个trait会在每个测试前跑迁移、测试后回滚,保证测试库干净。不过可以加个小验证,确认用户确实创建在测试库:
public function setUp() { parent::setUp(); $this->user = factory(User::class)->create(['password' => bcrypt('secret')]); // 打印测试库的用户数量,确认创建成功 dump(\DB::table('users')->count()); }
同时去你的开发数据库里看users表,这个测试用户应该不会出现在那里——如果测试库有、开发库没有,那用户创建是对的,问题就是应用实例没读测试库。
有时候应用会缓存旧的配置,导致即使换了环境文件也不生效。跑测试前先清一下配置缓存:
php artisan config:clear
如果是专门的测试环境,也可以指定环境:
php artisan config:clear --env=testing
如果上面的步骤还不行,可以在DuskTestCase里重写prepareEnvironment方法,强制设置测试环境的数据库配置,确保应用实例和测试用例用同一个库:
protected function prepareEnvironment() { parent::prepareEnvironment(); putenv('APP_ENV=testing'); putenv('DB_CONNECTION=sqlite'); putenv('DB_DATABASE='.database_path('testing.sqlite')); }
这样调整后,浏览器访问的应用实例就会和测试用例共用同一个SQLite测试数据库,登录测试应该就能正常匹配到你创建的测试用户了。
内容的提问来源于stack exchange,提问作者Ray

