If you’re running integration tests in your CI (you are, right?) - there’s a quick and easy win you can apply to make them run significantly faster.
This article discusses how you can speed up tests in CI in a project using:
- Symfony framework
- Doctrine ORM
- PHPUnit
- Gitlab.
In many cases - you’ll find yourself resetting the database state between the scenarios. In Symfony - you’ll often use fixtures to load the initial state. This usually works perfectly fine, unless you deal with secrets. If, for example, you’re loading a set of users and their passwords into the DB - you might see that it takes particularly long.
This is the relevant part of the fixtures documentation, which shows how Symfony handles loading user data.
It turns out, that the default encoder used by Symfony is based on bcrypt. While pretty safe - it also turns out to be incredibly slow, especially in case of CI/CD, which you’ll often run with restricted resources.
Guess what - you don’t really need all that security that bcrypt gives for running integration tests. You can choose a faster method for encoding, the only thing you need to do is to update Symfony’s configuration.
To override the default encoder for the test environment you need to create a security.yml file in the config/packages/test folder. You can use this snippet as the file contents:
Replacing bcrypt with sha512 should significantly reduce the time required for loading fixtures.
Here’s the original version, based on bcrypt:
Here’s the same with sha512:
Replacing the encoder decreased the time required to load the fixtures by 80%!
We can observe a similar result for the test suite, with bcrypt:
and with sha512:
We’ve just reduced the time required to run our integration test suite by 80%. Let’s write more tests now!