当前位置: 首页 > 知识库问答 >
问题:

为什么Jacoco分支机构的报道会说

谭池暝
2023-03-14

我的公司要求我们对新代码的测试覆盖率达到90%,对于Java代码,我使用gradle jacoco插件,这很好;然而,当分支数量开始呈指数增长时(夸张地说,这可能是几何增长),分支覆盖率很难提高到90%。

这里有一个很做作的例子:

public class Application {
    public static void test(boolean a, boolean b) {
        if (a && b) {
            System.out.println("true!");
        } else {
            System.out.println("false!");
        }
    }
}

而测试:

public class ApplicationTests {
    @Test
    public void test() {
        Application.test(true, true);
        Application.test(false, false);
    }
}

以下是报道的内容:

它还说,我错过了4个分支中的1个,或者换句话说,我覆盖了4个分支中的3个(75%的分支覆盖率)。

如果我在这里增加布尔数,分支数似乎是n*2,其中n是布尔数。所以3(a,b,c)变成6个分支,10个分支变成20个分支。所以我想我不明白在这种情况下有6个或20个分支意味着什么。

为了回答这个问题,我可以

A) 将jacoco配置为更直观,并将if/else条件视为始终具有两个分支(分支1是if执行时的分支,分支2是else执行时的分支)——子表达式的延迟执行可以作为行覆盖率或其他内容进行跟踪。

为了更完整地解释为什么它说有4,6,20个分支,这些如果/否则有2,3,10个布尔值组合成1个表达式。

编辑——为了澄清混淆的来源:

  1. 在这个例子中,当只有2个呼叫时,我如何覆盖3个分支
  2. 为什么3个布尔值的分支数(a

如果每个布尔值要么为真,要么为假,然后我用这两种状态调用函数,我怎么没有得到100%的分支覆盖率呢?我错过了一些东西。


共有3个答案

姚阳德
2023-03-14

在本例中,实际上只需要3个测试就可以获得100%的覆盖率。当两者都为假时测试案例不会提供任何额外的覆盖范围。凭直觉,这应该是有道理的。您希望它打印为true,除非至少有一个参数为false。

你构造代码的方式也会影响分支的数量。如果需求是做一件事,那么当它们都为真时,当它们中的任何一个为假时,你可以只做两个分支:

if (Stream.of(a,b).reduce(Boolean::logicalAnd).get(){
   System.out.println("true");
} else {
   System.out.println("false");
}

在一个只有两个输入的人为示例中,它看起来有点傻。如果在实际环境中有两个以上的输入,那么它就更有意义了。例如,你可以有一个类似于列表的东西

公良理
2023-03-14

当你在写条件时,比如

result a     b
true   true  true
false  false true
false  true  false
false  false false

因此,您需要调用此方法四次,以覆盖100%的覆盖率

您还可以创建一些实用程序类,根据参数的数量生成这些场景。

燕元明
2023-03-14

我想我现在已经弄明白了为什么分支数等于n*2,其中n是if()条件中布尔表达式的数目。

每个布尔表达式都是它自己的分支,所以在这个例子中,如果我们有一个

public class Application {
    public static void test(boolean a, boolean b, boolean c) {
        if (a && b && c) {
            System.out.println("true!");
        } else {
            System.out.println("false!");
        }
    }
}

例如if(a

在这种情况下,为了有效地覆盖所有6个分支,必须至少调用4次测试函数,以实现100%的分支覆盖率。

/*
 * Using ? to indicate it can be true or false,
 * it won't matter because the variable would never be read due to lazy evaluation.
 */
Application.test(true, true, true);  // +3 branches covered
Application.test(true, true, false); // +1 branch covered
Application.test(true, false, ?);    // +1 branch covered
Application.test(false, ?, ?);       // +1 branch covered
                                     // total: 6 branches

 类似资料:
  • 我将IntelliJ与Kotlin一起使用,并使用JaCoCo来计算测试覆盖率。在IntelliJ中,我的代码被覆盖了,但我没有看到我的Kotlin类的代码被覆盖的百分比。我只能在Java中看到它: 另一方面,我的Kotlin类被覆盖,我的代码是绿色或红色。此外,当我单击覆盖率窗口中的时,它会生成HTML页面,并且所有内容都很好地涵盖了。 你能告诉我为什么我在科特林课上看不到线覆盖率吗?

  • 我配置了两个项目来使用最新的jacoco版本0.7.8和最新的Arquillian jacoco扩展(1.0.09Alpha)。它就像一个魔咒(适用于jenkins和sonar 6.2)!但我有一个更大的项目,当我只启动Arquillian IT测试时,我的war归档文件会被创建,并有所有的类和测试。好的,当我运行相同的测试时,它的代码覆盖率,Arquillian归档文件中不包含任何类,并且有以下

  • 我想做一个分支 在分支和cond测试中,我必须检查代码中的每一个条件,所以例如在我的例子中,当字符串预计为null并且size=0时,我必须进行测试。我在我的测试类中看到我必须这样做: Bur java无法识别“预期”。如何检查字符串是否为null,以便?

  • 下面是Jacoco插件的样子。

  • 当我使用Jacoco代理运行单元测试时,我的本地Jacoco报告和SonarQube上的覆盖范围之间有一些差异。这似乎只影响包含嵌套类的文件。本地生成的报告具有外部类和所有内部类的覆盖信息,但是SonarQube上的覆盖数据只包括内部类。 例如,福。java包含外部类Foo和内部类Bar和Baz。 我的本地报告显示,Foo班的教学覆盖率为26%,Foo班为46%。吧台,Foo类为0%。巴兹;Foo

  • 代码在没有流量控制的情况下变得有点无聊; 对于初学者来说,Parrot知道分支和标签。 分支op等同于Perl的goto: branch TERRY JOHN: print "fjords\n" branch END MICHAEL: print " pining" branch GRAHAM TERRY: print "It's"