Laravel PHPUnit测试触发PostgreSQL连接数超限,求优化方案
解决Laravel 5.4 PHPUnit测试数据库连接数超限问题
我之前在跑大量数据库测试时也碰到过一模一样的问题,给你几个实用的解决思路,应该能帮你搞定:
1. 测试后主动断开数据库连接
既然DatabaseMigrations没有自动帮你清理连接,那我们可以手动在测试结束后断开所有连接,避免连接堆积导致超限。在你的测试基类或者具体测试类里添加tearDown方法:
protected function tearDown(): void { parent::tearDown(); // 遍历并断开所有数据库连接 foreach (\DB::getConnections() as $connection) { $connection->disconnect(); } }
这个方法会在每个测试方法执行完毕后,主动断开所有活跃的数据库连接,这样就不会让连接一直占用着,不用开启进程隔离也能控制连接数,测试速度不会受影响。
2. 限制PHPUnit并行测试的进程数
如果你还是想用进程隔离或者并行测试,可以通过控制进程数量来避免连接数超标。如果你的PHPUnit版本支持(PHPUnit 7及以上,Laravel 5.4对应的PHPUnit最低是5.7,你可以升级到7.x试试),可以用--parallel参数配合--processes指定并发进程数:
phpunit --parallel --processes=4
把--processes的值设成服务器能承受的范围,比如根据你的max_connection来算,假设每个测试进程会占用5个连接,那把进程数设成15左右就不会超过100的限制。这样既能利用并行提升速度,又不会触发连接数超限的问题。
3. 复用数据库迁移,用事务重置数据
如果你的测试不需要每次都修改数据库结构,只是需要重置数据,那可以把DatabaseMigrations换成DatabaseTransactions,并且只在测试类初始化时迁移一次数据库:
use Illuminate\Foundation\Testing\DatabaseTransactions; class YourTestClass extends TestCase { use DatabaseTransactions; public static function setUpBeforeClass() { parent::setUpBeforeClass(); // 所有测试开始前只执行一次迁移 \Artisan::call('migrate'); } public static function tearDownAfterClass() { // 所有测试结束后回滚迁移 \Artisan::call('migrate:rollback'); parent::tearDownAfterClass(); } }
这种方式下,整个测试类只会创建一次数据库连接并完成迁移,每个测试方法结束后用事务回滚数据,连接可以一直复用,不仅能解决连接数问题,测试速度也会比每次迁移快很多。
内容的提问来源于stack exchange,提问作者Samuel Dauzon
相关产品推荐
相关产品推荐

