Cover credit: XKCD
I'm currently following an online TDD course by Roy Osherove. I'm about half way through and although I have quite a bit of experience writing unit tests and using test frameworks I've gained a lot of knowledge from the course already. Here are some highlights about good unit tests and test reviews.
Roy stresses the importance of the three pillars of a good unit test:
If any of these are not taken into account during development developers are likely to drop unit tests all together because it will become a burden to use instead of an aid.
In one of the lessons Roy talks about the importance of test reviews. Having a high code coverage doesn't guarantee your code is good because you could be testing the wrong thing. Doing test reviews can help in ensuring the unit tests are correct. The unit tests themselves should be easy to read and understand to ensure maintainability.
- Unit tests should be easy to locate in the solution. Are the unit tests in a separate project?
- Readability is key in unit testing. Is there a clear naming convention?
- Naming the unit test projects:
- Naming the unit test classes:
(e.g. ShoppingBasketTests for the ShoppingBasket class)
- Naming the unit test methods:
(e.g. CalculateDiscount_ForTenProducts_ReturnsDiscountOf5Percent see Roy's blog for more examples)
- Logic in unit tests should be avoided. Are there any if/else, switch, try/catch or loop statements in the test? Then refactor the test into separate tests.
- Unit tests should be isolated and should always return the same result. Does the test have any dependencies to things beyond your control? (e.g. database, filesystem, DateTime, GUID)
- A unit test should only test one thing. Are there several asserts in a unit test? Verify if you really need all those asserts. If you do, move them to individual unit tests.