Java Test Coverage and The Missing Path



I started learning JUnit 4 and encountered the message "1 of 4 branches missed." when testing a code fragment like x && y where x and y depend on each other in a particular way. Here is my journey and a solution I don't like _at all_. Let's consider the following function
public boolean isPrintable(byte c) {
    return 0x20 <= c && c < 128;
}
and ignore the fact that it may not be perfect as criterium to determine if a byte is printable or not and focus on its test-ability instead. I'm using JUnit 4 and made sure to cover all three possible "branches" within this function: c being smaller than 0x20, c being between 0x20 and 128 and c being larger. Sadly, JUnit continues to complain with the message "1 of 4 branches missed." And I see why that may be: In the general situation, x && y has four possible combination of values of x and y to be fully covered: | | x==true | x==false | |--- |--- |--- | | y==true | Possibility 1 | Possibility 2 | | y==false | Possibility 3 | Possibility 4 | but for x=(0x20 <= c) and y=(c < 128) possibility 3 is not an option (because it would mean that c <= 0x20 but not c < 128). Hence understanding not only the syntax of the code but a bit of its semantic would be necessary to understand that possibility 3 cannot happen. But fuck it, it's java so let's get out our Collector-factory and adapter our wait towards a solution:
import java.util.stream.Collectors;
import java.util.stream.IntStream;

[...]
private boolean isWithinRange(int startInclusive, int value, int endExclusive) {
	return IntStream.range(startInclusive, endExclusive).boxed().collect(Collectors.toList()).contains(value);
}

public boolean isPrintable(byte c) {
	return isWithinRange(0x20, c, 128);
}
On a more serious note: please leave a comment here if you have a better idea. This is not meant as a real solution, please don't copy it and use it and tell people that it's a good idea!

Leave a Reply

Your email address will not be published. Required fields are marked *