A Stack Overflow thread inspired this series.
Every once in a while we stumble upon a particular unit test which takes ages to run, taking more than 10 seconds sometimes. Whenever a slow poke test is created, it takes more time to run the tests. In the beginning it seems to cause no harm, it’s one slow test, what could go wrong? you may ask.
Time goes by and tests are slower and slower, so the developers stop running the tests. When checking the unit tests, more than one-third are running slow and you don’t know how it happened.
Unit tests should run fast as possible, if the tests are slow, developers will start to avoid it or not bother to run them at all.
There are many cause for this problem, I’m going to list the most common.
The first one is the excessive setup for tests. When the tests have so much setup that it makes the tests slow.
Another possible cause is that the test have some hidden dependency and it cause the test to slow down because it’s trying to access the database.
One other cause, that is not that common, but I’ve seen sometimes, is when you want to simulate a timeout from a web service. This definitely will slow down the unit test, because a timeout usually can take a considerable amount of time to happen.
How to avoid
There are some approaches to take when end up in this situation, but the best thing to do is to prevent that it happens.
About excessive setup, instead of having a massive set up method, which contains configuration needed to all tests. Try to break up the setup method into smaller methods and use them in the arrange phase where it makes sense.
When encountering a hidden dependency, like a unit test trying to use the database, or trying to reach a file on the server. What you have to do isolate those dependencies in their own classes and expose it as an interface, to be able to mock them. If testing with the dependency is needed, move the test to its own project, because it configures an integration test.
In case the test has something related to wait an amount of time for something to happen. This kind of test should also moved to the integration test project. Even though they are unit tests, they are too slow to be considered unit tests.
One thing to have in mind is that unit test have to run fast, otherwise you may have a problem.
I’ve already talked about this and more techniques to write better unit tests in more depth, all the links are on the section bellow.