Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

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.

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_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 ?

like image 841
Alexandre Butynski Avatar asked Jul 24 '13 13:07

Alexandre Butynski


3 Answers

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.

like image 146
Maxime Fabre Avatar answered Oct 19 '22 03:10

Maxime Fabre


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

This worked well in Laravel 5.1

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

    parent::tearDown();
}
like image 4
Nate Ritter Avatar answered Oct 19 '22 05:10

Nate Ritter


For Laravel 4, you can use \DB::disconnect('connection') in your tearDown() function. See doc here: 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"

like image 3
efinal Avatar answered Oct 19 '22 04:10

efinal