Laravel Sail单步调试时数据库无测试生成数据的原因排查
问题场景
使用PhpStorm调试会创建数据库条目的Laravel Sail应用测试用例时,设置断点后手动检查数据库内容,断点位置查询数据库无对应数据。
已验证信息
- 单步调试配置完全正常
- 可通过docker-compose.yml中配置的端口转发正常连接数据库

- Laravel运行逻辑已确认对应数据库条目已创建

相关代码
代码中注释标注位置为断点:
... use Illuminate\Foundation\Testing\LazilyRefreshDatabase; ... class ObfuscatedTestClass extends TestCase { use LazilyRefreshDatabase; ... /** @test */ public function obfuscated_test_name() { Queue::fake(); ObfuscatedModelName::factory()->create(); // 断点位置 Queue::assertPushed(SyncLeaseWithAccountingApp::class); }
原因说明
该现象是LazilyRefreshDatabase特性的默认设计导致:
- 该特性为了提升测试运行速度、避免测试数据污染数据库,会在首次数据库操作前完成迁移后,全程开启未提交的数据库事务,所有测试内的写入操作都在该事务内执行
- 数据库的事务隔离机制决定了:未提交的事务内数据,仅对持有当前事务的数据库连接可见。测试代码内查询能读到数据,是因为查询走的是测试进程持有的事务连接;外部数据库客户端、PhpStorm数据库工具属于独立连接,无法读取未提交的事务数据
- 测试执行完成后,该事务会直接回滚,不会将测试数据持久化到磁盘。
调试方案
需要在断点时从外部工具查询测试写入的数据,可临时使用以下方案,调试完成后记得恢复配置避免影响测试效率或污染数据库:
- 临时将测试类引入的
LazilyRefreshDatabase替换为RefreshDatabase,同时在测试类中添加配置protected $connectionsToTransact = [];,关闭测试事务包裹,写入操作会直接提交到数据库 - 在断点前手动添加
DB::commit();代码提前提交事务,提交后外部连接即可查询到对应数据,调试完成后需手动清理测试库中的残留测试数据
内容的提问来源于stack exchange,提问作者Teltrix
相关产品推荐
相关产品推荐

