Easy code coverage reports with JMockIt
Von Carsten
In this blog post I want to describe how I use JMockIt not only for stubs and mocks, but for easy generation of code coverage reports while developing. JMockIt is my favorite tool for unit testing, because of it’s ease of use and the many options you get out of this framework. Only recently I decided to try the code coverage report that comes with JMockIt. I was searching for an easy way to monitor my test coverage while continuing development. I didn’t want another tool or another VM running a fancy code review tool. I just wanted to see what my current test cases are covering.
My class & test
For all of you wanting to get working code I give you a code kata that I created earlier. It’s the FizzBuzz kata, and it is already prepared to run with JMockIt.
FizzBuzz
package de.kopis.katas;
public class FizzBuzz {
public String generate(int number) {
String result = null;
if(number == 0) {
result = "0";
} else if(number % 3 == 0 && number % 5 == 0) {
result = "FizzBuzz";
} else if(number % 3 == 0) {
result = "Fizz";
} else if(number % 5 == 0) {
result = "Buzz";
} else {
result = String.valueOf(number);
}
if(result.contains("3")) {
result = "Fizz";
} else if(result.contains("5")) {
result = "Buzz";
}
return result;
}
}
FizzBuzzTest
package de.kopis.katas;
import static org.junit.Assert.*;
import mockit.integration.junit4.JMockit;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(JMockit.class)
public class FizzBuzzTest {
@Test
public void testValids() {
int[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 99, 180};
String[] expected = new String[] {"0", "1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "Fizz", "14", "FizzBuzz", "Fizz", "FizzBuzz"};
FizzBuzz fb = new FizzBuzz();
int index = 0;
for (int number : numbers) {
assertEquals(expected[index++], fb.generate(number));
}
}
@Test
public void testNewRequirements() {
int[] numbers = {13, 43, 99, 25, 55, 185, 90};
String[] expected = new String[] {"Fizz", "Fizz", "Fizz", "Buzz", "Buzz", "Buzz", "FizzBuzz"};
FizzBuzz fb = new FizzBuzz();
int index = 0;
for (int number : numbers) {
assertEquals(expected[index++], fb.generate(number));
}
}
}
How to create reports
To create code coverage reports with JMockIt you don’t have to go to hours and hours of tool setup before you get something done. Just drop these JAR in your classpath and you’re setup to go:
- jmockit.jar
jmockit-coverage.jar- jmockit-coverage-html[basic|full].jar
JDK_HOME/lib/tools.jar
When you’re working inside Eclipse I recommend adding the tools.jar as a user library. See the Eclipse documentation for some help with that.
Update: With Version 0.933+ you don’t need the JDK tools.jar
nor the jmockit-coverage.jar
in your classpath anymore. That reduces the setup to 2 JAR files. Notice that you only need the jmockit-coverage-htmlbasic.jar
if you intend to view the report only in Eclipse. The FULL report has additional information, that might be useful to you, but I prefer fast tests and simple reports while developing. Thanks for the tips, Rogério.
Now run your JUnit test and you get a directory coverage-report with an index.html file in it. Open it in your favorite browser (or with the Eclipse/Java EE internal web browser) and you see a report.
There is also a way of creating the reports from your ant script. But I’ll save that for a later blog post. If you want to try it yourself, go read the official documentation about JVM parameters.
What I think about it
This is as easy as code coverage gets: Covered lines are green, uncovered lines are red. You even get a little counter before each line telling you how many times this line was hit. Searching for performance bottlenecks? Start looking on high line counters. A whole method appearing in red? Examine the preconditions and write a test that calls that method.
Best thing on JMockIt coverage reports is: They don’t slow down your tests very much. You can just drop the JARs in your classpath and continue with your unit testing. If you want to check on your current coverage status, open the report and take a quick look. I think this is easy enough for every developer to integrate into his process. And you are already doing unit tests, right? So it shouldn’t take you more than a few mouse clicks to get a first coverage report…