Some time ago I wrote a wiki page for my Java team about Code Quality. In there, I had a piece about Unit Testing, and a nice spiel something along the lines of “Each Unit Test has a specific test case which should generally require only a single assert.” Of course there’s exceptions to the rules and depending on the language additional assertions may be required (for example, if something returns a list you’ll want to ensure the list isn’t null before performing that actual test case: if only for the fact we would rather see a test failure than an error). I’ve been hammering this thought into the team for nearly two years now, and it’s occurred to me that the majority of people feel like it’s a better idea to cram as many assertions as possible in a Unit Test.
So I started looking around to see what everyone thinks on the web, and it seems to come down to two trains of though:
Tests should fail for one reason, that’s why you use one assert.
Test one logical concept per test, you can have multiple assertions as they test the same concept.
I tend to be extremely strict on the first rule, but do see a sort of grey area where multiple assertions can be used. But I will always fight the same “concept” idea, being that each Object should be performing a single task, which each method performing a step in said task. If the steps turn out to be anything more than painfully simple, then we extract-class refactor away until our design as emerged. Sure Test Driven Development (TDD) people like me are considered nuts because we tend to write more Unit Tests than the rest of the sane world. But I like to think that by keeping the software simple, and the test cases simple with as few assertions as possible we can have more thorough test cases.
From my point of view sticking six assertions in a Unit Test is lazy and dangerous. You literally have to look at the entire unit test to figure out where and why it failed, as opposed to having a stand alone Unit Test which tells you exactly what failed and why.