Konstantinos Pittas

CTO of Archmule

Running PHPUnit tests in parallel

Posted on 16th of September 2017 in Laravel, PHP, Testing

Recently, I wanted to make my functional/integration (whatever you call them) tests to run faster. So I tried some optimizations that didn’t help a lot. In some cases, there were even some false positive/negative results.

Then I tried to run multiple tests in parallel together. This caused a problem though. All the tests were connecting and migrating/resetting the same database. However, this problem was easy to fix.

I used a PHP library called “fastest”. Even though most of their documentation's examples are about PHP, you could use it for stuff like:

$ ls | fastest "echo slow operation on {}" -vvv

I chose to install it globally to have it at my disposal for any project or occasion, without having to install it as a dependency.

But if your tests have to touch the database, this will not work. Mostly because when the one test will be adding a row, another one may be adding 10 more rows throwing off your tests that works just fine when running them separately.

One solution (and maybe the easier one) will be to use an in-memory SQLite database. Each database will not affect the other one and your tests will run successfully.

Though I don’t like this approach, as I want my test to hit a real database (MySQL in my case), as it would the same environment with production. But how would I define a different database for each test? Here comes the environment variables fastest provides.

I’m using Laravel, so to change my database configuration, I had to edit the config/database.php file. If you are using Symfony, or some other framework, check the fastest's documentation or your framework's.

I'll be running my test on my (still-rocking) 2012 MacBook Air, which has a Core 2 Duo CPU. So fastest by default (and probably for the best), will run one process per CPU core. So I've created 2 more databases (mydb_testing_1, mydb_testing_2). If you are running your tests on a, for example, 4-core CPU, you will have to add 2 more databases (mydb_testing_3, mydb_testing_4). And so on.