
- Image via Wikipedia
Pádraic Brady
The average for my current unit tests still hovers around three or four assertions per test method. And when I think about it, I see that the reason is that I’m not always taking the time to practice “one assertion per test” as a strict rule. Instead, it’s part of my problem-solving strategy when I start to get confused by my own tests; when the tests get so complex that I can’t quickly understand what’s going on where. Mock objects, in particular, contribute to this, since mock expectations specify what should happen later instead of testing what’s already happened.
Anyway, when I encounter this problem, known unsurprisingly as Complex Test or Obscure test, my first impulse is to make sure the code I’m testing (known as the system under test or SUT) is not too complex. Classes that are too large and methods that are too long are my prime examples of code that’s hard to test in a simple way. After I check the SUT, I look at the tests, and yes, then one of my goals is to move toward the “one assertion” ideal. It really is helpful at that point.
I’m open to the possibility that I should be more consistent in applying this principle. He may be right that there is a danger of “lazy/shallow testing”. In any case, as with all code, bugs and deficiencies are easier to spot the more readable it is.
![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_a.png?x-id=6e7736b2-1ac9-453f-9394-9b7870d0e941)
It’s pretty obvious that you sometimes need multiple assertions per test, since you need to assure that different parts of an object state have changed. That either means that you need to artificially create the very same object state in a different instance (which is not always possible) or you need multiple assertions, to ensure all expected parts of the object state changed and other parts did not.
Of course, such scenarios do not fit the typical “dice roling game” example used to illustrated unit testing.
I agree, although theoretically at least you could have a setup to create the object and then test different parts of it in different methods. That might be a lot of work for trivial gain, though. Alternatively, you can create custom assertions.
That is true, yes. As you said: A lot of work for trivial gain. I just dislike this “just to do it mantra-like correct” way of doing things.
To teach unexperienced testers how to write tests, the base rule must be “one assertion per test”. For experienced testers, who know how to test properly and who re-check frequently if they did not become lazy, this is just an efficiency waddle.
I agree that tests should be small and atomic and should only test one “event” or one “change” or however to call it, but I don’t think using only one assertion is a good way to archieve this. Escpecially when you want to prevent hidden “assertTrue(true)” you’ll need multiple assertions to make the test more robust.
I’m using simpleTest for unit testing and a test is usually a class. Now if you develop your test class PERFECTLY you and up with X tests with exactly X assertions. But practically this situation is no different than having 1 test with X assertions because the assertion tells you what you’re testing and the test are there just as markers (which can be written by comments). If the PERFECT way of writting tests is the same as the WORST way of writting tests there must be something wrong with a “perfect” test.
[...] Read more at One assertion per test—always? [...]