Fast PHPUnit tests

Testing your software is an important process. If you don't test, then you're falling behind your colleagues and cause a potential danger to your and your company's reputation and money. So, if you haven't started already, start now. Don't worry, it only looks confusing at first, but once you get used to it, you won't imagine working without testing. Your end-goal is to feel uncomfortable if you push untested code.

Nonetheless, this post is about how to make PHPUnit tests faster. Since I'm mainly a Laravel developer, I will focus on this framework. However, everything can be easily adapted to use on other frameworks as well.

It is nothing new or revolutionary, but I still sometimes see people running tests the hard and slow way. So here are the things you can do to speed up your tests.

Use SQLite

Many still use MySQL database for their tests. This is might look fine with a few tests, but as your application grows running your tests becomes a very long procedure. SQLite comes to save the day.
SQLite database is basically a single file. However, it can also be run in memory, which makes it even faster. Here is how to do it in Laravel: add these two lines to your phpunit.xml

<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>

That's it. Now just run ./vendor/bin/phpunit -c phpunit.xml
Now if you really need speed, it is possible to tell Laravel to skip running down migrations since we are getting a fresh database for each test anyway, but this is a trade of - your might miss some bugs in down migrations and they won't work when you actually need them.

And yes, there will be situations where you still need to use MySQL. A solution is to add those tests to group (for example @group mysql) and run them separately.

Use facile-it/paraunit

This composer library will run your tests in parallel, thus reducing test time even further. Installation is quite easy:

composer require --dev facile-it/paraunit

Now you have to run your tests like so: paraunit run -c phpunit.xml --parallel=4
4 should be the number of CPU units you have.

Results running with PHPUnit:

PHPUnit 6.5.5 by Sebastian Bergmann and contributors.

...............................................................  63 / 200 ( 31%)
............................................................... 126 / 200 ( 63%)
............................................................... 189 / 200 ( 94%)
...........                                                     200 / 200 (100%)

Time: 31.44 seconds, Memory: 44.00MB

OK (200 tests, 837 assertions)

Results running with paraunit:

PARAUNIT v.0.11
by Francesco Panina, Alessandro Lai & Shark Dev Team @ Facile.it
..........................................................................    74
..........................................................................   148
....................................................                         200


Execution time -- 00:00:23

Executed: 34 test classes, 200 tests

Bonus

Typing a test command often is annoying, so I'd like to share some ways of speeding that up as well.

  • Add a composer script:
    • "test": ["paraunit run -c phpunit.xml --parallel=4 --ansi"],
    • "cover": ["paraunit coverage -c phpunit.xml --parallel=4 --html=coverage-report --ansi"]
  • Add a bash alias:
    • alias t='composer test'
  • Configure PHPStorm shortcut to run tests according to context:
    • Open preferences -> Keymap. Search for "Run context configuration"
    • Configure PHP interpreter and Test Frameworks. If you need help on that, just comment.

So this is a short mini guide. If you know any other ways to speed things up please share. Also if you need help setting things up, contact me.

Have a nice day,
Ernestas.

Comments

Popular posts from this blog

Surround yourself with smarter than you

Redis smooth throttling