Wednesday, November 18, 2009

Code Coverage with Cobertura.

Overview
How to use it for black box testing.
Problems I faced while using it in my project

Overview
Recently I came across the tool named cobertura when I was chatting with one of my friend. It is used to find out the percentage code covered by test cases. So I decided to have a look at this and to find out if I can use that in my project.

Cobertura is a free java based tool used to find out the code coverage in java based application. It shows you the percentage of line covered and percentage of branch covered for each class. It also shows you the line covered in source code by marking it red, if you have source code available.

It's the amazing tool for both black box and white box testing. From the report you can find out how much code has covered and can write down further test cases if you think the code coverage is not enough and if you have code you can exactly come to know which functionalities or which part of functionality requires further test cases. And based on the report you can come to know whether product/project has tested properly and take the decision whether to ship the product or not? So let us see how it’s being done by cobertura?

Cobertura generates the another class files (instrumented class files) from your original class files which help in finding out the code coverrage. You can simply replace this with your original class files or you can set the classpath such that java runs instrumented class files instead of normal class files. It also generates cobertura.ser file along with instrumented classes. Which saves the information about the line and branch covered per classes and used to generate the report.

How to use it for black box testing.
Now let's see one by one how to generate the report.
The coubertra already provides the example for how to use cobertura. But the example is with Junit and ANT so people who want to use it for black box testing and doesn't have much experience with ANT and Junit may find it bit complicated.
In the below example we will create a simple java file and then will find out the code coverage after executing some test cases.

1. Download the coberura depends on your OS and JDK version from the following location. The latest version of the cobertura requires JDK 1.5
http://sourceforge.net/projects/cobertura/files/cobertura/

2. Extract the file at your desired location.
3. Set the location of cobertura.jar file in your classpath.
4. Create three folders named Src, Instrumented, and Reports inside d:\ (or any other directory, just changed the path accordingly in following command )
5. Now Create a simple java file as below in d:\src folder
import java.io.DataInputStream;
public class CodeCoverage {
public static void main(String args[]) throws Exception {
DataInputStream in = new DataInputStream(System.in);
System.out.print("Enter data: ");
int number = Integer.parseInt(in.readLine());;
if ( number > 10 ){
System.out.println(number+" It's greater then 10");
}
}
}

6. Compile the file and generate the class file.
7. Now move to cobertura folder (folder where you have extracted the downloaded file) and to generate the instrumented classes give following command on command prompt.
cobertura-instrument.bat --datafile d:\instrumented\cobertura.ser --destination d:\instrumented d:\src

After executing this command instrumented class file would be generated in d:\instrumented folder. And cobertura.ser file will also be generated in the same directory.

8. Now let's check the report before running the file. It should show 0% line coverage and 0% branch coverage as we haven't execute any of the test case. To generate the report run the following command on your command prompt.

cobertura-report.bat --datafile d:\instrumented\cobertura.ser --destination d:\reports d:\src






9. Now to see the report go to the d:\Reports and open the index.html file in any browser.
10. Now lets try to cover some code by executing the file. Move to instrumented folder and then run the file using following command on command prompt and give 9 as input when it asks for.

Java CodeCoverage

11. Now again generates the report same way as we generated before.




Problems I faced while using it in my project
Once I take the overview and find out how to use it for the black box testing. I decided to find out it for my current project.

If you have jar file or war file for the webapplication, it's quite easy as Cobertura directly generates corresponding instrumented jar or war files and you just need to replace it with original one. However, in our project we were using all class files scattered in different folders. So rather than checking whole application I decided to find out code coverage for part of the application first.

When tried to generate the instrumented class files it gave me following error.

Exception in thread "main" java.lang.UnsupportedClassVersionError: net/sourceforge/cobertura/instrument/Main


I got this error because I was using cobertura 1.9.3, which requires JDK 1.5 however; my project is older and uses JDK 1.3. Therefore, I then downloaded the older version of cobertura, cobertura 1.8 and problem get resolved. It successfully generated the instrumented classes and cobertura.ser file. I also checked out the report to make sure there isn't any error. I was happy to see it showed all the classed with 0% coverage.

Therefore, I finally replace the files inside my project directory with instrumented classes. I also copied the copbertura.jar file on project directory and set its path in classpath. However, I was not sure about where to put cobertura.ser file. Therefore, I decided to restart the webserver without putting it anywhere, because anyway it’s going to be generated. However, the weserver did not start, it hung. And when i check the logs I find out the following error.

Exception in thread "main" java.lang.NoClassDefFoundError: net/sourceforge/cobertura/coveragedata/HasBeenInstrumented

According to error webserver was not able to find the class file require to run instrumented classes. I was confused, as I have set the classpath proper.

However, after having a cup of tea, I finally figure out the root cause. Cobertura.jar file wasn't having the executable permission (Ahh, this happens when you are habituated using windows system). I change the permission and restart the web server with fingers crossed. And web server started successfully, I checked the reports and it was showing the coverage successfully. Finally I was revealed and happy.