2013-06-07 3 views
6

У меня есть класс в Sonar:Sonar покрытие ветви на объявлении класса

public class Foo { 
..... much code .... 
} 

И Sonar докладывают 1/2 ветвей, покрытых на этой public class Foo линии. Что это значит? Как вы проверяете строку, объявляющую класс?

Редактировать: в случае, если это имеет значение, это Sonar v3.5.

Edit 2: Скриншот показывает, что я имею в виду, обратите внимание на 1/2 рядом с «общественным классом» на линии 9. Когда парящий над этим я получить подсказку о том, «1 ветви покрыты тестами»

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

Edit # 3: Хорошо, на немного больше исследования, я сузили его до мельчайших сниппета я могу найти, что вызывает это:

public class Foo { 

    Foo(final String s) { 
     assert (s != null); 
    } 
} 

Если утверждают, не существует в конструкторе , флаг «N/2 филиалов закрыт» не получает созданный в Sonar. Если утверждение исчезнет, ​​флаг также исчезнет. Итак, мой угадывает в том, что он основан на ветвях внутри конструктора? (этот код имеет 0/4 ветвей, покрываемых для строки assert, и 0/2 для публичной строки класса).

+0

Объявление класса не является линией для покрытия. Без скриншота было бы довольно сложно понять и помочь вам. –

+0

@DavidRACODON: сделано. –

+0

Включены ли утверждения во время выполнения? – wchargin

ответ

7

Похоже, что это проблема, связанная с компонентом покрытия кода JaCoCo сонара. JaCoCo работает с компилированным байт-кодом, а не с Java-источником, а компилятор Java может создавать код, который напрямую не связан с исходным источником.

Глядя на the docs для JaCoCo, есть раздел, в котором говорится (выделено):

В некоторых ситуациях это не очевидно, почему отдельные линии действительно имеют выделения или имеют определенный цвет. Причина в том, что базовая библиотека покрытия кода JaCoCo работает только с файлами классов Java. В некоторых случаях компилятор Java создает дополнительный байтовый код для определенной строки исходного кода. Такие ситуации могут быть отфильтрованы в будущих версиях JaCoCo/EclEmma.

После ссылки в проходе приведет вас к FilteringOptions странице на сайте GH в Jacoco, и он упоминает несколько способов, в которых 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 

Примечание линии 7, которая представляет собой условный переход зависит от того, или нет, включены утверждения.Таким образом, если у вас есть класс с простым Java assert, вы будете иметь эту ветвь где-то в байт-коде, и это то, что приводит к предупреждению о покрытии «N/2-ветвей» в объявлении класса, где N равно либо 0 или 1 в зависимости от того, был ли класс испытанием (1) или нет (0).

Edit: обратите внимание, что это также упоминается в https://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions:

блоков, которые бросают AssertionErrors - Весь блок должен быть проигнорирован, если условие (если утверждение певд AssertionError!)

Смежные вопросы