26

有没有一种简单的方法可以告诉我缺少哪个分支?即我有一些这样的代码:

if (x || y) {
    // do stuff
}

在突出显示的报道中,Eclipse 中有一个黄点,上面写着:

错过了 4 个分支中的 1 个

但我想知道缺少哪个分支。

4

7 回答 7

16

可以xy是什么?

  • true || true(由于 JVM 优化而未涵盖:如果第一个条件为true,则由于短路评估而不会评估第二个条件)
  • false || true真的
  • true || false真的
  • false || false假的
于 2013-03-19T06:55:14.523 回答
14

有一个非常简单的解决方法 - 只需将每个逻辑谓词放在单独的行上,如下所示:

if (x 
    || y) {
    System.out.println("BRANCH: " + x + ", " + y);
    // Do stuff
}

现在,当您运行分析时,标记应直接指向丢失的分支。添加覆盖率后,您可以以正确的方式重新格式化您的代码。

于 2017-05-11T10:02:35.830 回答
12

Eclemma 的父母 jacoco 的 github 存储库上的一个解决问题表明,这样的功能实际上有点难以包含。

但是,即使没有 Eclemma 功能,如果目标只是找出在特定情况下遗漏的分支,您也可以检测代码以进行跟踪。最简单的例子是老式的打印语句:

if (x || y) {
    System.out.println("BRANCH: " + x + ", " + y);
    // Do stuff
}

然后查看输出并查看您实际点击了哪些分支(例如java ... | grep "BRANCH:" | sort | uniq)。(我知道,不是很令人满意。)

于 2016-05-11T16:50:51.827 回答
5

答案是true|| true没有被覆盖。

这是因为一旦 JVM 发现第一个条件为真,它就不会运行第二个条件(已优化),这意味着这部分代码永远不会运行。

正如 Maroun 所说,4 个分支中有 3 个将允许条件通过。如果您仍然担心代码覆盖率,您可以将条件重构为 a&&而不是 a ||

(x || y)相同(!(!x && !y)),这将允许您测试所有条件,因为现在只有三个分支。

条件的原始形式经常出现在保护语句中:

if (obj == null || obj.hasError())
{
    throw new RuntimeException();
}

这将永远不允许您检查objis nullAND 是否有错误,因为它会抛出空指针异常。

如果代码覆盖率很重要,那么只需使用这种形式:

if (!(obj != null && !obj.hasError()))
{
    throw new RuntimeException();
}
于 2013-11-12T04:05:43.647 回答
0

块内的嵌套语句if或扩展您的xy谓词的语句可能存在隐式分支。

阅读: http ://emma.sourceforge.net/faq.html#q.fractional.examples

于 2013-03-19T08:02:55.230 回答
0

以下表达式的结果是什么?

  • true || true真的
  • true || false真的
  • false || true真的
  • false || false假的

如果您在第一种和第二种情况下注意到第一个参数为TRUE,则​​无需检查第二个参数。

  • true && true真的
  • true && false假的
  • false && true假的
  • false && false假的

或者,如果您看到使用AND运算符的场景,如果第一个参数为FALSE ,则您永远不需要检查第二个参数。

因此,您永远无法检查 4 个分支中的 1 个分支。

于 2019-05-15T16:17:30.393 回答
-1

为了获得全面覆盖,避免编译器的隐式选择,您必须将 if 语句重写为两个

if (x) {
    // do stuff
} else if (y) {
    // do the same stuff
}

这将得到全面覆盖,但会被正确标记为冗余代码。看到问题后,我宁愿忍受黄线,也不愿将这种混乱的结构添加到代码中。

于 2020-12-02T01:27:59.590 回答