Laravel & PHPUnit : allow process isolation to prevent Mysql Too many connections error

时间:2022-02-23 07:02:26

Since four months we build a complex web app with Laravel 4 with a good unit test coverage. Now we have 159 tests and 592 assertions to prevent against regression and allow us to easily refactor our app.

自从四个月以来,我们用Laravel 4构建了一个复杂的Web应用程序,具有良好的单元测试覆盖率。现在我们有159个测试和592个断言来防止回归,并允许我们轻松地重构我们的应用程序。

Nice picture but since few days we have the following error in the last tests :

很好的图片,但由于几天我们在最后的测试中有以下错误:

PDOException: SQLSTATE[HY000] [1040] Too many connections

The reason is simple : all tests run in the same process and MySQL allow only a certain number of access in the same time. Now, we have too many tests. If i delete few tests in the middle of my test suite, the last ones pass.

原因很简单:所有测试都在同一个进程中运行,而MySQL只允许同时进行一定数量的访问。现在,我们有太多的测试。如果我在我的测试套件中间删除了一些测试,那么最后的测试就会通过。

The solution could be to run PHPUnit in process isolation like in the config below but the Laravel tests do not seem to be launched like that. I get an other error in each test :

解决方案可能是在进程隔离中运行PHPUnit,如下面的配置,但Laravel测试似乎没有像那样启动。我在每次测试中都会遇到其他错误:

PHPUnit_Framework_Exception: Notice: Constant LARAVEL_START already defined in /.../.../autoload.php on line 3
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
     backupStaticAttributes="false"
     bootstrap="bootstrap/autoload.php"
     colors="true"
     convertErrorsToExceptions="true"
     convertNoticesToExceptions="true"
     convertWarningsToExceptions="true"
     processIsolation="true"
     stopOnFailure="false"
     syntaxCheck="false"
>

</phpunit>

So my question is : how could I configure Laravel tests to work with processIsolation="true" or do you see an other solution to my problem ?

所以我的问题是:如何配置Laravel测试以使用processIsolation =“true”,或者您是否看到了我的问题的其他解决方案?

4 个解决方案

#1


3  

For Laravel 4, you can use \DB::disconnect('connection') in your tearDown() function. See doc here: http://laravel.com/docs/database#accessing-connections

对于Laravel 4,您可以在tearDown()函数中使用\ DB :: disconnect('connection')。请参阅此处的doc:http://laravel.com/docs/database#accessing-connections

"If you need to disconnect from the given database due to exceeding the underyling PDO instance's max_connections limit, use the disconnect method"

“如果由于超出了底层PDO实例的max_connections限制而需要断开与给定数据库的连接,请使用disconnect方法”

#2


4  

You can now do DB::connection()->setPdo(null) to close the connection in your tests's tearDown, tha should solve it. If that doesn't work, you can do unset($this->app['db']) in any test extending Laravel's TestCase.

您现在可以执行DB :: connection() - > setPdo(null)来关闭测试的tearDown中的连接,应该解决它。如果这不起作用,你可以在任何扩展Laravel的TestCase的测试中取消设置($ this-> app ['db'])。

#3


2  

I would take a look at Mocks and remove your MySQL dependency: https://github.com/padraic/mockery#mocking-public-static-methods

我会看看Mocks并删除你的MySQL依赖:https://github.com/padraic/mockery#mocking-public-static-methods

Going forward, I would actually suggest focusing more on testing your SQL. My firm recently spent a good amount hiring DBAs that really turned our legacy slowness around.

展望未来,我实际上建议更多地关注测试SQL。我公司最近花了大量资金聘请DBA,这真的让我们的遗产变得缓慢。

#4


1  

As per http://www.neontsunami.com/posts/too-many-connections-using-phpunit-for-testing-laravel-51

根据http://www.neontsunami.com/posts/too-many-connections-using-phpunit-for-testing-laravel-51

This worked well in Laravel 5.1

这在Laravel 5.1中运作良好

public function tearDown()
{
    $this->beforeApplicationDestroyed(function () {
        DB::disconnect();
    });

    parent::tearDown();
}

#1


3  

For Laravel 4, you can use \DB::disconnect('connection') in your tearDown() function. See doc here: http://laravel.com/docs/database#accessing-connections

对于Laravel 4,您可以在tearDown()函数中使用\ DB :: disconnect('connection')。请参阅此处的doc:http://laravel.com/docs/database#accessing-connections

"If you need to disconnect from the given database due to exceeding the underyling PDO instance's max_connections limit, use the disconnect method"

“如果由于超出了底层PDO实例的max_connections限制而需要断开与给定数据库的连接,请使用disconnect方法”

#2


4  

You can now do DB::connection()->setPdo(null) to close the connection in your tests's tearDown, tha should solve it. If that doesn't work, you can do unset($this->app['db']) in any test extending Laravel's TestCase.

您现在可以执行DB :: connection() - > setPdo(null)来关闭测试的tearDown中的连接,应该解决它。如果这不起作用,你可以在任何扩展Laravel的TestCase的测试中取消设置($ this-> app ['db'])。

#3


2  

I would take a look at Mocks and remove your MySQL dependency: https://github.com/padraic/mockery#mocking-public-static-methods

我会看看Mocks并删除你的MySQL依赖:https://github.com/padraic/mockery#mocking-public-static-methods

Going forward, I would actually suggest focusing more on testing your SQL. My firm recently spent a good amount hiring DBAs that really turned our legacy slowness around.

展望未来,我实际上建议更多地关注测试SQL。我公司最近花了大量资金聘请DBA,这真的让我们的遗产变得缓慢。

#4


1  

As per http://www.neontsunami.com/posts/too-many-connections-using-phpunit-for-testing-laravel-51

根据http://www.neontsunami.com/posts/too-many-connections-using-phpunit-for-testing-laravel-51

This worked well in Laravel 5.1

这在Laravel 5.1中运作良好

public function tearDown()
{
    $this->beforeApplicationDestroyed(function () {
        DB::disconnect();
    });

    parent::tearDown();
}