Einführung in JaCoCo

1. Übersicht

Die Codeabdeckung ist eine Softwaremetrik, mit der gemessen wird, wie viele Zeilen unseres Codes während automatisierter Tests ausgeführt werden.

In diesem Artikel werden einige praktische Aspekte der Verwendung von JaCoCo vorgestellt - einem Generator für Codeabdeckungsberichte für Java-Projekte.

2. Maven-Konfiguration

Um mit JaCoCo arbeiten zu können, müssen wir dieses Maven-Plugin in unserer Datei pom.xml deklarieren :

 org.jacoco jacoco-maven-plugin 0.7.7.201606060606    prepare-agent    report prepare-package  report     

Der hier angegebene Link führt Sie immer zur neuesten Version des Plugins im zentralen Maven-Repository.

3. Code Coverage Reports

Bevor wir uns mit den Codeabdeckungsfunktionen von JaCoCo befassen, benötigen wir ein Codebeispiel. Hier ist eine einfache Java-Funktion, die prüft, ob eine Zeichenfolge vorwärts und rückwärts gleich lautet:

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 Gang gesetzt. Auf diese Weise wird im Zielverzeichnis - target / jacoco.exec - ein Abdeckungsbericht im Binärformat erstellt.

Natürlich können wir die Ausgabe nicht im Alleingang interpretieren, aber andere Tools und Plugins können dies - z . B. Sonar Qube .

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

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

Unter dem im Bericht angegebenen Link - Palindrome.java - können wir eine detailliertere Ansicht für jede Java-Klasse durchgehen:

Beachten Sie, dass Sie dank des EclEmma Eclipse-Plugins die Codeabdeckung mithilfe von JaCoCo in Eclipse ohne Konfiguration problemlos verwalten können.

4. Berichtsanalyse

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

Die 38 von JaCoCo im Bericht gezeigten Anweisungen beziehen sich auf die Bytecode-Anweisungen im Gegensatz zu normalen Java-Code-Anweisungen.

Mit JaCoCo-Berichten können Sie die Codeabdeckung visuell analysieren, indem Sie Diamanten mit Farben für Zweige und Hintergrundfarben für Linien verwenden:

  • Roter Diamant bedeutet, dass während der Testphase keine Verzweigungen ausgeübt wurden.
  • Gelber Diamant zeigt an, dass der Code teilweise abgedeckt ist - einige Zweige wurden nicht ausgeübt.
  • Grüner Diamant bedeutet, dass alle Zweige während des Tests trainiert wurden.

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

JaCoCo bietet hauptsächlich drei wichtige Metriken:

  • Die Zeilenabdeckung spiegelt die Menge an Code wider, die basierend auf der Anzahl der von den Tests aufgerufenen Java-Bytecode-Anweisungen ausgeführt wurde.
  • Die Zweigabdeckung zeigt den Prozentsatz der ausgeübten Zweige im Code an - normalerweise bezogen auf if / else- und switch- Anweisungen.
  • Die zyklomatische Komplexität spiegelt die Komplexität des Codes wider, indem die Anzahl der Pfade angegeben wird, die erforderlich sind, um alle möglichen Pfade in einem Code durch lineare Kombination abzudecken.

Um ein triviales Beispiel zu nennen: Wenn der Code keine if- oder switch- Anweisungen enthält, ist die zyklomatische Komplexität 1, da wir nur einen Ausführungspfad benötigen, um den gesamten Code abzudecken.

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

5. Konzeptaufschlüsselung

JaCoCo wird als Java-Agent ausgeführt und ist für die Instrumentierung des Bytecodes während der Ausführung der Tests verantwortlich. JaCoCo bohrt in jede Anweisung und zeigt, welche Linien während jedes Tests trainiert werden.

Um Erfassungsdaten zu erfassen, verwendet JaCoCo ASM für die Code-Instrumentierung im laufenden Betrieb und empfängt dabei Ereignisse von der JVM-Tool- Oberfläche :

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

Sie können dem offiziellen Dokumentationslink folgen, um weitere Informationen zum JaCoCo-Design zu erhalten.

6. Code Coverage Score

Nachdem wir nun ein wenig über die Funktionsweise von JaCoCo wissen, wollen wir unseren Code Coverage Score verbessern.

Um eine 100% ige Codeabdeckung zu erreichen, müssen Tests eingeführt werden, die die im ersten Bericht gezeigten fehlenden Teile 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")); }

Now we can say that we have enough tests to cover our the entire code, but to make sure of that, let's run the Maven command mvn jacoco:report to publish the coverage report:

As you can see all lines/branches/paths in our code are fully covered:

In real world project, and as developments go further, we need to keep in track the code coverage score.

JaCoCo offers a simple way of declaring minimum requirements that should be met, otherwise the build will fail.

We can do that by adding the following check goal in our pom.xml file:

 jacoco-check  check     PACKAGE   LINE COVEREDRATIO 0.50      

As you can probably guess, we're limiting here the minimum score for lines coverage to 50%.

The jacoco:check goal is bound to verify, so we can run the Maven command – mvn clean verify to check whether the rules are respected or not. The logs will show something like:

[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. Conclusion

In this article we've seen how to make use of JaCoCo maven plugin to generate code coverage reports for Java projects.

Keep in mind though, 100% code coverage does not necessary reflects effective testing, as it only reflects the amount of code exercised during tests. In a previous article, we've talked about mutation testing as a more sophisticated way to track tests effectiveness compared to ordinary code coverage.

Sie können das in diesem Artikel bereitgestellte Beispiel im verknüpften GitHub-Projekt überprüfen .