The following simple code snippet contains a while
-loop that looks as if it could be infinite:
def findDivisor(n: Int): Int = {
require(n >= 2)
var i = 2
while (true) {
if (n % i == 0) {
return i
} else {
// do-nothing branch
}
i += 1
}
// $COVERAGE-OFF$
throw new Error("unreachable")
// $COVERAGE-ON$
}
Basic math guarantees that this method always terminates (even if it cannot find a proper divisor, it must stop at n
).
Despite the $COVERAGE-OFF$
right after the while
-loop, Scoverage (and maybe some other coverage tools) will complain, and compute only 75% branch coverage (because while
counts as a branch point, and the false
branch is never taken before return
).
Moving the // $COVERAGE-OFF$
around, e.g. before the closing }
of the while
-body does not help either.
How do I force it to ignore the impossible branch?
Just wrap the while(true) {
loop head into a separate pair of $COVERAGE-OFF$
-$COVERAGE-ON$
comments:
def findDivisor(n: Int): Int = {
require(n >= 2)
var i = 2
// $COVERAGE-OFF$
while (true) {
// $COVERAGE-ON$
if (n % i == 0) {
return i
} else {
// do-nothing branch
}
i += 1
// $COVERAGE-OFF$
}
throw new Error("unreachable")
// $COVERAGE-ON$
}
Now Scoverage makes sure that each statement in the body of the while
-loop is covered, but it ignores the false
-branch, and reports 100%
test coverage e.g. after the following simple test:
"Whatever" should "do something" in {
MyObjectName.findDivisor(57) should be(3)
}