Oh yes; another article that attempts to defy traditional thinking. First it was that static methods are fine. Then I told you that Singletons are fine. Now, I’m saying a case can be made for multiple assertions in a single test. This will be a short one, too.
Why Only One?
First, I’ll look at the reasons that people give for using only one assertion per test. Firstly, it helps with maintainability. A test should only focus on one behavior so that you can just look at the name or description of the test and know what went wrong. Tied in with that is the fact that, once you add multiple assertions into a test, it gets harder to come up with a name or description. Lastly, with multiple assertions, if multiple of them fail, you only get to find out about one of them until you fix it and run the tests again.
A Case for Multiples
First off, I am NOT arguing for simply having multiple assertions in one test. I’m suggesting that we not be afraid of combination assertions. In the Hamcrest library, this is accomplished via the
anyOf() matchers; In AssertJ, this is just done via the chaining of assertion methods. Most assertion/matcher libraries provide this ability, but other than AssertJ users, I don’t see it used a lot, and think it should be used more.
Some reasons against multiple assertions don’t apply in this, case, and the others are entirely case-dependent. The last one about only one thing failing is only partially true now. Yes, there is only one failed test (unless there’s a testing framework that will split that into multiple failures), but the message mentions multiple failures, so you can see them all at once.
There is a point where they can get overused, though. Luckily, as far as I know, every assertion combination system out there uses the same “subject” for each assertion in the combination, which helps restrict how many assertions can be done in a test before you must do an additional full assertion.
Still, a decent guideline for telling if you’re good is if the description of the test is easy to write without including “and” or “correctly”. The first directly suggests that it’s testing multiple things, while the second can easily hide “and” under the guise of “all these things need to happen to be correct”. Sometimes that second one can be okay, but if the description can’t be changed to something good, then it probably isn’t. Also, I can’t guarantee that, just because the description worked out, it’s okay to use combination assertions. Try to use your best judgement.
So ends the ____ are Fine article series. I may do more in the future, but I’m done defending pragmatism for a while 🙂
Next time, I’m going to do a pros and cons list for Python; the Yin and Yang of Python (it’s fun because the Python logo is sort of Yin Yang-ish).