Parallel PHPUnit testing in integration tests

This is a good question: preparing for parallel unit tests is going to require learning some new Best Practices, and I suspect some of them are going to slow our tests down.

At the highest level, the advice is: avoid testing with a database wherever possible. Abstract all interactions with your database, and then mock that class. But you've already noted your question is about integration tests, where this is not possible.

When using PDO, I generally use sqlite::memory: Each test gets its own database. It is anonymous and automatically cleaned up when the test ends. (But I noted some problems with this when you real application is not using sqlite: Suggestions to avoid DB deps when using an in-memory sqlite DB to speed up unit tests )

When using a database that does not have an in-memory choice, create the database with a random name. If the parallelization is at the PHPUnit process level, quite coarse, you could use the process pid. But that has no real advantages over a random name. (I know PHP is single-threaded, but perhaps in future we would have a custom phpUnit module, that uses threads to run tests in parallel; we might as well be ready for that.)

If you have the xUnit Test Patterns book, chapter 13 is about testing databases (relatively short). Chapters 8 and 9 on transient vs. persistent fixtures are useful too. And, of course, most of the book is on abstraction layers to make mocking easier :-)


There is also this awesome library (fastest) for executing tests in parallel. It is optimized for functional/integration tests, giving an easy way to work with N databases in parallel.

Our old codebase run in 30 minutes, now in 7 minutes with 4 Processors.

Features

  • Functional tests could use a database per processor using the environment variable.
  • Tests are randomized by default.
  • Is not coupled with PhpUnit you could run any command.
  • Is developed in PHP with no dependencies.
  • As input you could use a phpunit.xml.dist file or use pipe.
  • Includes a Behat extension to easily pipe scenarios into fastest.
  • Increase Verbosity with -v option.

Usage

find tests/ -name "*Test.php" | ./bin/fastest "bin/phpunit -c app {};"