Increase Golang web app testing speed by over 2 times with parallel testing and more
We're all familiar with how tests get slower as we add more over time. If you're not already using parallel testing in Go, this article will give you an example of how to implement it in a web application. In one of my projects, I managed to decrease test time from 40s to just over 10s by employing these techniques.
The Solution
The easiest way to get major speed improvements is to add t.Parallel() to every top level test function.
func TestMyFunc(t *testing.T) {
t.Parallel() // add this line
... testing code
}
There's a pretty high chance that your test might break. The biggest culprit is having have singletons in your code. If any test uses a shared state, whether in a singleton or not, you cannot make that particular test parallel. Other tests can still be parallel. Some other obstacles could be caused by bad testing practice such as relying on previous test states for the next test, or using the same rows in a table etc. You can solve this by ensuring each test are designed to run in isolation.
Other Techniques
Another simple way to decrease test run time is simply not cleaning up the tests every run. That means not deleting from the database etc. If your tests are designed in isolation, this will be an easy change. The other benefit from this technique is having your tests run in a "dirty" state that mimics production environments.
You can take it a step further and break tests in smaller units like so:
func TestMyFunc(t *testing.T) {
t.Run("t1", func (t *testing.T) {
t.Parallel()
})
t.Run("t2", func (t *testing.T) {
t.Parallel()
})
}
This will also help during debugging because you can isolate the test i.e. -run TestMyFunc/t2
You can shave off a few more seconds by running your code and database off a ramdisk. See how I run Go code from ramdisk.
Lastly, if you're not already using a tool to automatically run your code when you save a file, you should start now to save plenty of time during development.