声纳分支覆盖类声明

Ada*_*kin 6 java code-coverage sonarqube

我在声纳有一堂课:

public class Foo {
..... much code ....
}
Run Code Online (Sandbox Code Playgroud)

Sonar正在报告该public class Foo线路上的1/2分支机构.这是什么意思?你如何测试一个声明一个类的行?

编辑:如果重要,这是Sonar v3.5.

编辑2:截图显示我的意思,请注意第9行"公共类"旁边的1/2.当悬停在此上方时,我得到一个工具提示,指出"测试覆盖了1个分支"

http://img829.imageshack.us/img829/2626/screenshot20130607at120.png

编辑#3:好的,经过一番调查,我把它缩小到我能找到的最小片段,触发了这个:

public class Foo {

    Foo(final String s) {
        assert (s != null);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果构造函数中不存在该断言,则在Sonar中不会生成"N/2分支覆盖"标志.如果断言消失了,那么旗帜也会消失.所以我的猜测是它基于构造函数中的分支?(此代码的断言行覆盖0/4分支,公共类行覆盖0/2).

Ada*_*kin 7

看起来这是与Sonar的JaCoCo代码覆盖组件相关的问题.JaCoCo使用编译的字节码而不是Java源代码,Java编译器可以生成与底层源不直接相关的代码.

望着的文档进行JaCoCo,还有其内容(强调)的一段:

在某些情况下,不明显的是,为什么特定的线条具有突出显示或具有特定颜色.原因是底层代码覆盖库JaCoCo仅适用于Java类文件.在某些情况下,Java编译器为特定的源代码行创建额外的字节代码.这种情况可能会被未来版本的JaCoCo/EclEmma过滤掉.

在段落中的链接后,您将进入Jacoco GH站点上的FilteringOptions页面,它提到了JDK可能产生的一些代码,这些代码将触发这些"虚假"代码覆盖警告.

然而,这不是在这里(或不完全)发挥作用.

如上所述,JaCoCo使用Java字节码,因此编译器生成的任何代码都不会直接归属于源代码.

在我的具体情况中,我有一个assert在源代码中代表断言发生点的分支,但也处于"全局"级别.如果你看一下Foo上面定义的类的字节码(做一个javap -c Foo),你会看到:

Compiled from "Foo.java"
public class Foo extends java.lang.Object{
static final boolean $assertionsDisabled;

Foo(java.lang.String);
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   getstatic   #2; //Field $assertionsDisabled:Z
   7:   ifne    22
   10:  aload_1
   11:  ifnonnull   22
   14:  new #3; //class java/lang/AssertionError
   17:  dup
   18:  invokespecial   #4; //Method java/lang/AssertionError."<init>":()V
   21:  athrow
   22:  return

static {};
  Code:
   0:   ldc_w   #5; //class Foo
   3:   invokevirtual   #6; //Method java/lang/Class.desiredAssertionStatus:()Z
   6:   ifne    13
   9:   iconst_1
   10:  goto    14
   13:  iconst_0
   14:  putstatic   #2; //Field $assertionsDisabled:Z
   17:  return
Run Code Online (Sandbox Code Playgroud)

注意第7行,它是一个条件分支,取决于是否启用了断言.因此,如果你有一个普通Java的类assert,你将在字节码中的某个地方有这个分支,这就是在类声明中产生"N/2个分支执行"覆盖警告的地方,其中N是0或者1取决于该类是否曾通过测试(1)或不测试(0).

编辑:请注意,这也在https://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions中提到:

抛出AssertionErrors的块 - 如果条件(如果!断言抛出新的AssertionError),则应忽略整个块