Kent Beck told me years ago, if the code does not need to work, then there is no need to test it. He continued and observed, why bother writing it if it does not need to work. Since hearing that and discovering how frequently I make coding mistakes, I want thorough tests.
Maybe you are asking yourself “I’ve got integration and system tests, why do I need unit tests?”. The answer is simple, simple math.
The only practical way to know that every line of code is doing what you think it should do, is to have unit tests that exercise and check each line. Higher level tests, because of the number of combinations, can not practically test each line as the system grows larger and object interactions increase. For example, how many tests are be needed to thoroughly test these three objects if you test them together?
Did you do the math? It requires multiplication. You would need thousand tests to test this simple network of objects. In most cases, it is not practical. Who would bother to spend the time to write 1000 tests for such a simple system? (Maybe someone in medical electronics, aviation or space travel.)
No consider a unit test strategy for the same three objects.
The numbers game works in favor of unit testing. Addition is needed instead of multiplication to calculate the test count. You need a total of 30 unit tests to fully test each object. Then you’d be smart to write the necessary higher level tests to check each interface is being used properly and the system is meeting its requirements.
Its not a matter of needing one and not the other. Unit tests and higher level tests are both needed. They just serve different purposes. Unit tests tell the programmer that the code is doing what they think it should do. They write those tests. Higher level tests (by whatever name you like: BDD, ATDD, Acceptance, System, integration, and load tests) cannot be thorough, but they demonstrate that the system is meeting its requirements.
Pingback: Five Blogs – 13 August 2014 | 5blogs
Fully agree that we can use unit test to ease the workload for functional/system level testing. But it’s usually not necessary that we need 1000 test cases for the example even without unit test. For example, we can use pairwise approach (http://www.pairwise.org/).
Well stated James. Although I’m biased as a tool vendor in this space, one of the other significant benefits of unit testing is a reduction in the complexity of designing tests, since the pre-conditions are certainly simpler when testing is done at lower level of granularity. Related to this, is the ability to easily stimulate error-handling constructs that may be impossible to stimulate in a completely integrated system.
@Lifen, pairwise look interesting. It may be a way to cut down on the number of tests, but there still will be way too many tests for a test strategy that only tests at the higher levels. Thanks for the link!
@John, I completely agree.