Thursday, July 17, 2008

Code coverage: a tool against unused and untested code

I'm an agile developer because I write my code incrementally i.e. only what I need today. I usually start writing the code by writing Unit Test - it really works and it really helps me understand what should be implemented and how system should behave (I will leave the subject of convincing people, who are new to unit testing, to do "write-test-first" for a separate post). OK - I usually do this but sometimes it's difficult or I'm just too impatient to see the result and start with the implementation and write unit test later. How do I know which packages/classes/methods are tested and which are "not touched" by any single unit test? How do I know that my code is really used somewhere by other parts of the developed system? This is the work for code coverage tool.

What is code coverage
According to Wikipedia article code coverage is a measure used in software testing. It describes the degree to which the source code of a program has been tested. It is a form of testing that inspects the code directly and is therefore a form of white box testing. For me as an agile developer code that is not tested is not used and not needed. I mean it! If the code is not tested and not used it is the code that "will be needed in the future". I don't accept such code - if I need something in the future I will simply add it - if I don't need something at this moment I have to remove it (because not used/tested code may contain bugs).
If some part of my code is not tested it means that I don't need it - that is true in almost 100% of cases. This way code coverage tool shows me not only which parts of the software are tested but also which parts of the system are not used and can be removed.

Example
I use Cobertura code coverage tool that calculates the percentage of code accessed by tests. Let's take a look at this simple project containing 19 classes:

This report does not tell many things - useful information is that line coverage of the whole project is 70% and the branch coverage is 25%. The only conclusion you should get looking at this report is that the project is not well tested (or contain some unnecessary code).

If you navigate deeper and take a look at some classes you could see something like this:

This report tells me as a developer that e.g. getDocs() and setDocs(String) methods are not visited during unit testing. I assume that these methods are not needed thus I remove them (!). You should consider doing the same.
If it occurs that you need those methods write unit test that covers this class and those methods immediately.

Bad example from the past
I have very good example how not to write code and how code coverage tool can help you catching such problems. In the past when I had to write some exception hierarchy I started writing exception class with implementing all constructors from the superclass i.e. java.lang.Exception - just in case ;) Here it is:

This means that I had 4 constructors in each exception class but was using usually only one... Why to write the constructor that nobody wants? There is no need to do it!

Consider following Cobertura report:

This is how I write code now :) I start with the unit test and add the code incrementally only when needed. And Cobertura (code coverage tool) helps me assuring myself I'm using my code.
This way I'm sure at least two things:
1. My code is well tested (maybe not well tested but at least I know to what extent it is tested)
2. I've written only the code that is needed - there is no "dead" code

Conclusion
The best way to write code is to start with unit test and to write it incrementally - implement ONLY what you need today. If you are not feeling good with test-first principle and you prefer write an implementation first (you shouldn't) make sure you use your code. One way to do this is to employ code coverage tool (open-source, or commercial ones like Clover). Such tool will show you which parts of your system need testing or simply which parts of your system are not used and can be removed. After each build I check code coverage report to see how much work I have and I really don't like red color (I love green instead :)

What do you think about usefulness of code coverage tools? How do you write your code - are you really writing your code incrementally? How do you ensure that?

Originally published on AgileSoftwareDevelopment.com

1 comment:

Raine said...

This is great info to know.