Es scheint, dass dies ein Problem in Bezug auf die JaCoCo Code Coverage Komponente von Sonar ist. JaCoCo arbeitet mit kompiliertem Bytecode anstatt mit Java-Quelle, und der Java-Compiler kann Code erzeugen, der nicht direkt mit der zugrunde liegenden Quelle in Beziehung steht.
bei the docs der Suche nach JaCoCo, gibt es einen Abschnitt, der (Hervorhebung hinzugefügt) lautet:
In manchen Situationen ist es nicht offensichtlich ist, warum bestimmte Linien hervorgehoben haben oder eine bestimmte Farbe haben. Der Grund dafür ist, dass die zugrunde liegende Code-Coverage-Bibliothek JaCoCo nur an Java-Klassendateien arbeitet. In einigen Fällen erstellt der Java-Compiler zusätzlichen Bytecode für eine bestimmte Zeile des Quellcodes. Solche Situationen können durch zukünftige Versionen von JaCoCo/EclEmma gefiltert werden.
Nach dem Link in der Passage führt Sie zur FilteringOptions Seite auf dem GH-Website Jacoco, und es nennt eine ganze Reihe von Möglichkeiten, wie die JDK möglicherweise Code erzeugen kann, die diese „unechten“ Code-Coverage-Warnungen auslösen .
Das ist jedoch nicht, was hier (oder nicht genau) spielt.
Wie bereits erwähnt, arbeitet JaCoCo mit Java-Bytecode, so dass jeder Code, der vom Compiler erzeugt wird, der nicht direkt der Quelle zugeordnet ist, zur Abdeckung zählt.
In meinem speziellen Fall hatte ich eine assert
, die in der Quelle eine Verzweigung an dem Punkt darstellt, an dem die Bestätigung stattfindet, aber auch auf einer "globalen" Ebene. Wenn Sie an der Bytecode für die Foo
Klasse siehe oben definiert (mit dem javap -c Foo
), werden Sie sehen:
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
Hinweis Linie 7, die eine bedingte Verzweigung abhängig ist, ob oder nicht Behauptungen aktiviert sind.Wenn Sie also eine Klasse mit einem einfachen Java assert
darin haben, haben Sie diesen Zweig irgendwo im Bytecode, und dies erzeugt die Überdeckungswarnung "N/2 Zweige ausgeführt" für die Klassendeklaration, wobei N entweder 0 ist oder 1 abhängig davon, ob die Klasse jemals durch einen Test (1) oder nicht (0) ausgeübt wurde.
Edit: beachten Sie, dass dies auch in https://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions erwähnt wird:
Blöcke, die AssertionErrors werfen - Entire Block, wenn eine Bedingung ignoriert werden sollte (wenn Behauptung neue AssertionError werfen!)
Eine Erklärung Klasse ist keine zu überwindende Linie. Ohne einen Screenshot wäre es ziemlich schwer zu verstehen und Ihnen zu helfen. –
@DavidRACODON: fertig. –
Sind Zusicherungen zur Laufzeit aktiviert? – wchargin