有没有简单的方法可以告诉我我缺少哪个分支? 比如,我有这样一些代码:
if (x || y) {
// do stuff
}
在覆盖率提示中,Eclipse 中有一个黄点,上面写着:
1 of 4 branches missed
但是我想知道哪一个分支缺失了。
有没有简单的方法可以告诉我我缺少哪个分支? 比如,我有这样一些代码:
if (x || y) {
// do stuff
}
在覆盖率提示中,Eclipse 中有一个黄点,上面写着:
1 of 4 branches missed
但是我想知道哪一个分支缺失了。
有一个非常简单的解决方法 - 只需将每个逻辑谓词放在单独的一行上,就像这样:
if (x
|| y) {
System.out.println("BRANCH: " + x + ", " + y);
// Do stuff
}
现在当您运行分析时,标记应该直接指向被错过的分支。在添加了覆盖率后,您可以正确地重新格式化代码。
x
和y
可以是什么?
true || true
是 true(由于JVM优化,第一个条件为true
时,不会评估第二个条件,因为采用短路求值)false || true
是 truetrue || false
是 truefalse || false
是 false||
运算符的语言规范中,如果第一个操作数为真,则不得评估第二个操作数。这是一个硬性的功能要求,而不是一种优化,并且定义在Java语言中,而不是JVM中。 - SusanWGitHub仓库中的一个未解决问题表明,在Eclemma的父级项目jacoco上实现这样一个功能可能会有一定难度。
但是,即使没有Eclemma的功能,如果目标只是找出特定情况下错过的分支,您可以对代码进行仪器化以进行跟踪。最简单的示例是老式的打印语句:
if (x || y) {
System.out.println("BRANCH: " + x + ", " + y);
// Do stuff
}
然后查看输出并确定实际命中的分支(例如:java ... | grep "BRANCH:" | sort | uniq
)。 (我知道这不是很令人满意。)
return expr1 && expr2
这样的行上遇到了相同的错误;我的单元测试期望返回值为 true。因此它必须已经访问了这两个表达式。 :/ - juanmftrue || true
没有被覆盖。&&
而不是||
。
(x || y)
与(!(!x && !y))
相同,这将允许您测试所有条件,因为现在只有三个分支。if (obj == null || obj.hasError())
{
throw new RuntimeException();
}
这种方式永远无法检查obj
是否为null
并且有错误,因为它会抛出Null Pointer Exception异常。
如果代码覆盖率很重要,那么请使用以下形式:
if (!(obj != null && !obj.hasError()))
{
throw new RuntimeException();
}
|
或&
,否则你永远无法获得完整的分支覆盖。 - tkokasih在if
块内部的嵌套语句或扩展x
或y
谓词的语句中,可能存在隐式分支。
阅读此文档: http://emma.sourceforge.net/faq.html#q.fractional.examples
以下表达式的结果将是什么?
true || true
为truetrue || false
为truefalse || true
为truefalse || false
为false如果您注意到在第1和第2种情况下,当第1个参数为TRUE时,您不需要检查第2个参数。
true && true
为truetrue && false
为falsefalse && true
为falsefalse && false
为false或者,如果您看到使用AND运算符的情况,如果第一个参数为FALSE,则永远不需要检查第二个参数。
因此,您永远无法检查4个分支中的1个分支。
if (x) {
// do stuff
} else if (y) {
// do the same stuff
}
这将获得完整的覆盖范围,但会被正确标记为冗余代码。我宁愿在看到问题后接受黄色线条,也不愿将这种混乱的结构添加到代码中。