Introduktion till JaCoCo

1. Översikt

Kodtäckning är ett mjukvarumätvärde som används för att mäta hur många rader i vår kod som körs under automatiserade tester.

I den här artikeln kommer vi att gå igenom några praktiska aspekter av att använda JaCoCo - en kodtäckningsrapportgenerator för Java-projekt.

2. Maven-konfiguration

För att komma igång med JaCoCo måste vi förklara detta maven-plugin i vår pom.xml- fil:

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

Länken som tillhandahålls här tidigare kommer alltid att leda dig till den senaste versionen av plugin-programmet i maven central repository.

3. Kodtäckningsrapporter

Innan vi börjar titta på JaCoCos kodtäckningsmöjligheter måste vi ha ett kodprov. Här är en enkel Java-funktion som kontrollerar om en sträng läser samma bakåt och framåt:

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); } }

Allt vi behöver nu är ett enkelt JUnit- test:

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

När du kör testet med JUnit sätts JaCoCo-agenten automatiskt i rörelse, vilket skapar en täckningsrapport i binärt format i målkatalogen - target / jacoco.exec.

Självklart kan vi inte tolka utdata på egen hand, men andra verktyg och plugins kan - t.ex. Sonar Qube .

Den goda nyheten är att vi kan använda jacoco: rapportmålet för att generera läsbara kodtäckningsrapporter i flera format - t.ex. HTML, CSV och XML.

Vi kan nu ta en titt på sidan target / site / jacoco / index.html för att se hur den genererade rapporten ser ut:

Efter länken i rapporten - Palindrome.java kan vi gå igenom en mer detaljerad vy för varje Java-klass:

Observera att du rakt kan hantera kodtäckning hjälp JaCoCo inne Eclipse med noll konfiguration , tack vare EclEmma Eclipse plugin.

4. Rapportanalys

Vår rapport visar 21% instruktionstäckning, 17% filialtäckning, 3/5 för cyklomatisk komplexitet och så vidare.

38 instruktionerna från JaCoCo i rapporten hänvisar till bytekod instruktionerna i motsats till vanliga Java-kod instruktioner.

JaCoCo-rapporter hjälper dig att visuellt analysera kodtäckning genom att använda diamanter med färger för grenar och bakgrundsfärger för linjer:

  • Röd diamant innebär att inga grenar har utövats under testfasen.
  • Gul diamant visar att koden är delvis täckt - vissa grenar har inte utövats.
  • Grön diamant innebär att alla grenar har utövats under testet.

Samma färgkod gäller bakgrundsfärgen men för linjetäckning.

JaCoCo tillhandahåller huvudsakligen tre viktiga mätvärden:

  • Linjetäckningen återspeglar mängden kod som har utövats baserat på antalet Java-byte-kodinstruktioner som anropas av testerna.
  • Filialtäckning visar procentandelen utövade filialer i koden - vanligtvis relaterad till if / else och switch- uttalanden.
  • Cyklomatisk komplexitet återspeglar komplexitet i kod genom att ge antalet vägar som behövs för att täcka alla möjliga vägar i en kod genom linjär kombination.

För att ta ett trivialt exempel, om det inte finns några if- eller switch- uttalanden i koden, kommer den cyklomatiska komplexiteten att vara 1, eftersom vi bara behöver en exekveringsväg för att täcka hela koden.

Generellt återspeglar den cyklomatiska komplexiteten antalet testfall som vi behöver genomföra för att täcka hela koden.

5. Fördelning av koncept

JaCoCo körs som en Java-agent , det är ansvarigt för att instrumentera bytecode medan du kör testerna. JaCoCo borrar in i varje instruktion och visar vilka linjer som utövas under varje test.

För att samla in täckningsdata använder JaCoCo ASM för kodinstrumentering i farten och tar emot händelser från JVM Tool Interface i processen:

Det är också möjligt att köra JaCoCo-agenten i serverläge. I det här fallet kan vi köra våra tester med jacoco: dumpa som ett mål, att initiera en dumpningsförfrågan.

Du kan följa den officiella dokumentationslänken för mer detaljerad information om JaCoCo-design.

6. Kodtäckningsresultat

Nu när vi vet lite om hur JaCoCo fungerar, låt oss förbättra vår kodtäckningspoäng.

För att uppnå 100% kodtäckning måste vi införa tester som täcker de saknade delarna som visas i den ursprungliga rapporten:

@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")); }

Nu kan vi säga att vi har tillräckligt med test för att täcka hela koden, men för att försäkra oss om det, låt oss köra kommandot Maven mvn jacoco: rapport för att publicera täckningsrapporten:

Som du kan se är alla rader / grenar / banor i vår kod helt täckta:

I verkliga projekt, och när utvecklingen går längre, måste vi hålla koll på kodens täckningsresultat.

JaCoCo erbjuder ett enkelt sätt att deklarera minimikrav som ska uppfyllas, annars kommer build misslyckas.

Vi kan göra det genom att lägga till följande kontrollmål i vår pom.xml- fil:

 jacoco-check  check     PACKAGE   LINE COVEREDRATIO 0.50      

Som du förmodligen kan gissa begränsar vi här lägsta poäng för linjetäckning till 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.

Du kan kolla in exemplet i den här artikeln i det länkade GitHub-projektet .