14 April 2009

Emma - Java Code Coverage Made Easy (Part 2)

This is the second post on Java code coverage with Emma. In previous post, we discussed about Code Coverage and introduction to Emma. In this post, we will discuss about how to install Emma and do the basic code coverage with an example and screenshots. After you complete the reading of this post and previous post, you should be able to download Emma, install it and run Emma from command line. Towards the end, we will also discuss about how to get HTML report and interpret simple Emma report. It will be good if you can download Emma from here and use it side by side as you read this post. Please make sure that you download the binary of Emma and not the source version. The binary version of Emma should be sufficient to do this. Along with this, you need to have Java compiler and Java Runtime Environment to compile your Java classes. In order to give a picture of how Emma works and process involved, let us take the toughest approach of running Emma from command line rather than integrating with IDE. In later posts, we will discuss about IDE integration (Eclipse/Netbeans) to make developers life easier.

Downloading and Installing Emma
Emma comes in three different versions - binaries with examples, source and libraries. In order to do this example, we need to download "binaries with examples and documentation". You can directly download it form Sourceforge.net or you can access Sourceforge project via Emma home page. Irrespective of the way you choose, please make sure that you download Emma binaries with example version. After downloading emma..zip, unzip in a directory. You find three directories "docs", "examples" and "libs". Inside the directory "lib", you will find two JAR files emma.jar and emma_ant.jar. For time being, we will not be requiring emma_ant.jar as it is used to integrate with "ant" which we will cover in subsequent posts. The JAR "emma.jar" is the tool that we will be using throughout this example. Apart from the examples given in this post, you can also try to play with the examples that comes with Emma. Take "emma.jar" from the extracted directory and copy it to the directory where we have our examples. The following picture shows my setup.

Emma.jar and Examples

Java Program Example
Consider the following Java classes. Greater.java is the main class that we are going to test and measure coverage with the help of GreaterTestDriver.java. The class "GreaterTestDriver.java" mimics the testing of the class "Greater.java".



Greater.java has compare method and it prints out the largest of two numbers. GreaterTestDriver.java creates an object of "Greater.java" and invokes compare method passing values 10 and 5 respectively. For values 10 and 5, if block in the method compare is executed and else part will not be executed which our coverage has to pin point.

Running Emma
Running Emma is simple and you only need to specify emma.jar in the classpath and run your application using "emmarun" command. In our case, it is running the test driver "GreaterTestDriver" class. Once you run Emma and after you application exits, Emma prints the coverage results in a text file "converage.txt".

Running Emma and Getting output in text file

If you look at the report "coverage.txt", it gives the coverage data at package, block, method, class and line level.

You can also run Emma and get report in HTML format. Again it is very simple and you need to specify that in command line options (refer the last boxitem to know more about command line options used in this post).

Emma with HTML Reporting

So far you have run Emma and got the HTML report. But the data given by Emma shows the coverage results but the information is not sufficient. It will be helpful to merge the results with source code. Emma can also pin point which lines are executed and which lines are not executed. Yet again, the step is simple and following example is self explanatory.

Emma Reporting with Source Code

In the above report, the lines that are highlighted in green color are the ones that are tested at least once and the lines that are in pink color are not tested. In ideal case, you need to improve your test suite to cover the lines that are highlighted in pink color. As an exercise, can you achieve 100% coverage in Greater.java?

Command options used in this example

# In order to run Emma from command line and to get report in test file
java -cp emma.jar emmarun -cp . example.GreaterTestDriver
# In order to run Emma from command line and get report in HTML but without Source Code
java -cp emma.jar emmarun -r html -cp . example.GreaterTestDriver
# In order to run Emma from command line, get report in HTML and merge the result with Source Code
java -cp emma.jar emmarun -sp . -r html -cp . example.GreaterTestDrive

In this post we saw only on-the-fly instrumentation and in upcoming posts we will discuss other features of Emma such as Eclipse (and Netbeans) integration, off-line instrumentation, integrating with ant and merging data of multiple sessions, integrating with Tomcat.

I have also come up with a little interactive presentation with flash using Wink on Emma. It can be accessed through this link

1 comment:

davecode said...

Hi there, I try your example, but it didn't work... Could you pls tell me what's wrong... here is what i did...
my working directory is EmmaTest:

C:\Users\MyUser\EmmaTest>dir /b

C:\Users\829929\EmmaTest>java -cp emma.jar emmarun -cp . example.GreaterTestDriver
EMMA: collecting runtime coverage data ...
EMMA: runtime controller started on port [47653]
EMMA: no metadata collected at runtime [no reports generated]
[EMMA v2.1, build 5320 (stable)]
emmarun: [MAIN_CLASS_NOT_FOUND] application class [example.GreaterTestDriver] could not be loaded
Exception in thread "main" com.vladium.emma.EMMARuntimeException: [MAIN_CLASS_NOT_FOUND] application class [example.GreaterTestDriver] could not be loaded
at com.vladium.emma.run.RunProcessor._run(RunProcessor.java:473)
at com.vladium.emma.run.RunProcessor.run(RunProcessor.java:107)
at com.vladium.emma.run.runCommand.run(runCommand.java:263)
at emmarun.main(emmarun.java:27)
Caused by: java.lang.ClassNotFoundException: example.GreaterTestDriver
at com.vladium.emma.run.InstrClassLoader.findClass(InstrClassLoader.java:253)
at com.vladium.emma.run.InstrClassLoader.loadClass(InstrClassLoader.java:122)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at com.vladium.emma.run.RunProcessor._run(RunProcessor.java:468)

Greater.java class
package example;

public class Greater {
public void compare (int a, int b){
if ( a > b)
System.out.println(a + " is greater");
System.out.println(b + " is greater");

GreaterTestDriver.java class
package example;

public class GreaterTestDriver {
public static void main (String[] args){
System.out.println("Greater Test version 1");
Greater gt = new Greater();


hope to hear from you... thanks in advance