Einführung in JaCoCo

1. Überblick

  • Code Coverage ** ist eine Softwaremetrik, mit der gemessen wird, wie viele Zeilen unseres Codes bei automatisierten Tests ausgeführt werden.

In diesem Artikel werden wir einige praktische Aspekte der Verwendung von JaCoCo - einem Generator für die Codeabdeckung für Java-Projekte - durchgehen.

2. Maven Konfiguration

Um mit JaCoCo loslegen zu können, müssen wir dies https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.jacoco%22%20A%3A% 22jacoco-maven-plugin% 22[maven-plugin]in unserer pom.xml -Datei:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.7.201606060606</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Der zuvor bereitgestellte Link führt Sie immer zur neuesten Version des Plugins im zentralen Repository von maven.

3. Berichte zur Codeabdeckung

Bevor wir uns die Möglichkeiten der JaCoCo-Codeabdeckung ansehen, benötigen wir ein Codebeispiel. Hier ist eine einfache Java-Funktion, die prüft, ob eine Zeichenfolge dasselbe Zeichen vorwärts und rückwärts liest:

public boolean isPalindrome(String inputString) {
    if (inputString.length() == 0) {
        return true;
    } else {
        char firstChar = inputString.charAt(0);
        char lastChar = inputString.charAt(inputString.length() - 1);
        String mid = inputString.substring(1, inputString.length() - 1);
        return (firstChar == lastChar) && isPalindrome(mid);
    }
}

Jetzt brauchen wir nur noch einen einfachen JUnit -Test:

@Test
public void whenEmptyString__thenAccept() {
    Palindrome palindromeTester = new Palindrome();
    assertTrue(palindromeTester.isPalindrome(""));
}

Wenn Sie den Test mit JUnit ausführen, wird der JaCoCo-Agent automatisch in Bewegung gesetzt. Daher wird ein Abdeckungsbericht im Binärformat ** im Zielverzeichnis target/jacoco.exec. erstellt

Natürlich können wir die Ausgabe nicht alleine interpretieren, aber andere Tools und Plugins können - z.

Die gute Nachricht ist, dass wir das Ziel jacoco: report verwenden können, um lesbare Berichte zur Codeabdeckung in verschiedenen Formaten zu erstellen - z. HTML, CSV und XML.

Wir können jetzt beispielsweise auf der Seite target/site/jacoco/index.html nachsehen, wie der generierte Bericht aussieht:

Bild:/uploads/coverage-3.png[Berichterstattung]

Über den im Bericht angegebenen Link - Palindrome.java können Sie eine detailliertere Ansicht für jede Java-Klasse aufrufen:

Bild

Beachten Sie, dass Sie die Codeabdeckung mithilfe von JaCoCo in Eclipse mit Zero Configuration einfach verwalten können.

4. Berichtsanalyse

Unser Bericht zeigt 21% Anweisungen, 17% Filialen, 3/5 für zyklomatische Komplexität und so weiter.

Die von JaCoCo im Bericht angezeigten 38 Anweisungen beziehen sich auf die Bytecode-Anweisungen und nicht auf gewöhnliche Java-Code-Anweisungen.

JaCoCo-Berichte helfen Ihnen bei der visuellen Analyse der Codeabdeckung, indem Sie Diamanten mit Farben für Verzweigungen und Hintergrundfarben für Linien verwenden:

  • Roter Diamant bedeutet, dass während des Projekts keine Äste ausgeübt wurden

Testphase.

  • Gelbe Raute zeigt an, dass der Code teilweise abgedeckt ist - einige

Zweige wurden nicht ausgeübt.

  • Grüner Diamant bedeutet, dass alle Äste während des Trainings ausgeübt wurden

Prüfung.

Der gleiche Farbcode gilt für die Hintergrundfarbe, jedoch für die Linienabdeckung.

JaCoCo liefert hauptsächlich drei wichtige Messgrößen:

  • Zeilenabdeckung spiegelt den Umfang des Codes wider, der ausgeübt wurde

basierend auf der Anzahl der von den Tests aufgerufenen Java-Bytecode-Anweisungen.

  • Branchenabdeckung zeigt den Prozentsatz der ausgeübten Niederlassungen in der

code - normalerweise in Verbindung mit den Anweisungen if/else und switch .

  • Zyklomatische Komplexität spiegelt die Komplexität des Codes wider, indem er das gibt

Anzahl der Pfade, die erforderlich sind, um alle möglichen Pfade in einem Code durch lineare Kombination abzudecken.

Ein einfaches Beispiel: Wenn der Code keine if - oder switch -Anweisungen enthält, ist die zyklomatische Komplexität 1, da wir nur einen Ausführungspfad für den gesamten Code benötigen.

Im Allgemeinen spiegelt die zyklomatische Komplexität die Anzahl der Testfälle wider, die implementiert werden müssen, um den gesamten Code abzudecken.

5. Konzeptzusammenbruch

JaCoCo läuft als Java-Agent und ist für die Instrumentierung des Bytecodes während der Tests verantwortlich. JaCoCo führt jede Anweisung durch und zeigt, welche Linien bei jedem Test ausgeübt werden.

Um Coverage-Daten zu sammeln, verwendet JaCoCo ASM für die Codeinstrumentierung im laufenden Betrieb und empfängt Ereignisse von JVM Tool Interface im Prozess:

jacoco concept

Es ist auch möglich, den JaCoCo-Agenten im Server-Modus auszuführen. In diesem Fall können wir unsere Tests mit jacoco: dump als Ziel ausführen, um eine Speicherabzugsanforderung zu initiieren.

Weitere Informationen zum JaCoCo-Design finden Sie unter http://www.eclemma.org/jacoco/trunk/doc/implementation.html (Offizieller Dokumentationslink).

6. Code Coverage Score

Nun, da wir ein bisschen wissen, wie JaCoCo funktioniert, verbessern wir unsere Codeabdeckung.

Um eine 100% ige Codeabdeckung zu erreichen, müssen Tests eingeführt werden, die die fehlenden Teile des ursprünglichen Berichts abdecken:

@Test
public void whenPalindrom__thenAccept() {
    Palindrome palindromeTester = new Palindrome();
    assertTrue(palindromeTester.isPalindrome("noon"));
}

@Test
public void whenNearPalindrom__thanReject(){
    Palindrome palindromeTester = new Palindrome();
    assertFalse(palindromeTester.isPalindrome("neon"));
}

Jetzt können wir sagen, dass wir genug Tests haben, um den gesamten Code abzudecken. Um dies sicherzustellen, führen wir den Maven-Befehl mvn jacoco: report aus, um den Abdeckungsbericht zu veröffentlichen:

Bild:/uploads/coverage-2.png[Berichterstattung]

Wie Sie sehen, sind alle Zeilen/Zweige/Pfade in unserem Code vollständig abgedeckt:

Bild:/uploads/coverage-1.png[Berichterstattung]

In realen Projekten und bei fortschreitenden Entwicklungen müssen wir den Codeabdeckungswert verfolgen.

JaCoCo bietet eine einfache Möglichkeit, Mindestanforderungen anzugeben, die erfüllt sein sollten, andernfalls schlägt der Build fehl.

Wir können dies tun, indem Sie das folgende check -Ziel in unsere pom.xml -Datei einfügen:

<execution>
    <id>jacoco-check</id>
    <goals>
        <goal>check</goal>
    </goals>
    <configuration>
        <rules>
            <rule>
                <element>PACKAGE</element>
                <limits>
                    <limit>
                        <counter>LINE</counter>
                        <value>COVEREDRATIO</value>
                        <minimum>0.50</minimum>
                    </limit>
                </limits>
            </rule>
        </rules>
    </configuration>
</execution>

Wie Sie sich vermutlich vorstellen können, beschränken wir hier die Mindestpunktzahl für die Leitungsabdeckung auf 50%.

Das jacoco: check -Ziel ist gebunden an verify , sodass wir den Maven-Befehl mvn clean verify ausführen können, um zu prüfen, ob die Regeln eingehalten werden oder nicht. Die Protokolle zeigen etwa Folgendes:

----[ERROR]Failed to execute goal org.jacoco:jacoco-maven-plugin:0.7.7.201606060606:check
  (jacoco-check) on project mutation-testing: Coverage checks have not been met.
----

7. Fazit

In diesem Artikel haben wir gesehen, wie Sie das JaCoCo-Maven-Plugin verwenden, um Berichte zur Codeabdeckung für Java-Projekte zu generieren.

Beachten Sie jedoch, dass 100% Code Coverage nicht für effektive Tests erforderlich ist , da nur die Menge an Code berücksichtigt wird, die während der Tests verwendet wird. In einem früheren Artikel haben wir über mutation testing als differenziertere Methode zur Nachverfolgung der Wirksamkeit von Tests im Vergleich zur gewöhnlichen Code-Abdeckung gesprochen.

Sie können das Beispiel in diesem Artikel in der verlinkten GitHub-Projekt überprüfen.