Въведение в JaCoCo

1. Общ преглед

Покритието на кода е софтуерна метрика, използвана за измерване на колко реда от нашия код се изпълняват по време на автоматизирани тестове.

В тази статия ще разгледаме някои практически аспекти на използването на JaCoCo - генератор на отчети за покритие на код за Java проекти.

2. Конфигурация на Maven

За да стартираме и работим с JaCoCo, трябва да декларираме този плъгин maven в нашия файл pom.xml :

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

Предоставената тук връзка винаги ще ви отведе до най-новата версия на приставката в централното хранилище на maven.

3. Доклади за покритие на кода

Преди да започнем да разглеждаме възможностите за покритие на кода на JaCoCo, трябва да имаме пример за код. Ето една проста Java функция, която проверява дали низ чете еднакво назад и напред:

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

Всичко, от което се нуждаем сега, е прост JUnit тест:

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

Изпълнението на теста с помощта на JUnit автоматично ще задейства агента JaCoCo, като по този начин ще създаде отчет за покритие в двоичен формат в целевата директория - target / jacoco.exec.

Очевидно не можем да интерпретираме изхода еднолично, но други инструменти и плъгини могат - напр. Sonar Qube .

Добрата новина е, че можем да използваме целта jacoco: report, за да генерираме четливи отчети за покритие на кода в няколко формата - например HTML, CSV и XML.

Сега можем да разгледаме например страницата target / site / jacoco / index.html, за да видим как изглежда генерираният отчет:

Следвайки връзката, предоставена в отчета - Palindrome.java , можем да разгледаме по-подробен изглед за всеки клас Java:

Имайте предвид, че можете директно да управлявате покритието на кода, като използвате JaCoCo вътре в Eclipse с нулева конфигурация , благодарение на приставката EclEmma Eclipse.

4. Анализ на отчета

Нашият доклад показва 21% покритие на инструкциите, 17% покритие на клонове, 3/5 за цикломатична сложност и така нататък.

38-те инструкции, показани от JaCoCo в доклада, се отнасят до инструкциите за байт код, за разлика от обикновените инструкции за Java код.

Отчетите на JaCoCo ви помагат да анализирате визуално покритието на кода, като използвате диаманти с цветове за клони и цветове на фона за линии:

  • Червеният диамант означава, че по време на тестовата фаза не са упражнявани клони.
  • Жълтият диамант показва, че кодът е частично покрит - някои клонове не са упражнени.
  • Зеленият диамант означава, че всички клони са били упражнени по време на теста.

Същият цветен код се отнася за цвета на фона, но за покритие на линии.

JaCoCo предоставя основно три важни показателя:

  • Покритието на линиите отразява количеството код, което е било упражнено въз основа на броя инструкции за байтов код на Java, извикани от тестовете.
  • Покритието на клонове показва процента на упражнени клонове в кода - обикновено е свързано с if / else и инструкции за превключване .
  • Цикломатичната сложност отразява сложността на кода, като дава броя на пътищата, необходими за покриване на всички възможни пътища в код чрез линейна комбинация.

За да вземем тривиален пример, ако в кода няма изрази if или switch , цикломатичната сложност ще бъде 1, тъй като се нуждаем само от един път за изпълнение, за да покрием целия код.

Като цяло цикломатичната сложност отразява броя на тестовите случаи, които трябва да приложим, за да покрием целия код.

5. Разбивка на концепцията

JaCoCo работи като агент Java , той е отговорен за instrumenting байткод по време на движение на тестовете. JaCoCo разгражда всяка инструкция и показва кои линии се упражняват по време на всеки тест.

За да събира данни за покритието, JaCoCo използва ASM за кодова апаратура в движение, получавайки събития от интерфейса на JVM Tool в процеса:

Възможно е също да стартирате агент JaCoCo в сървърния режим, в този случай можем да стартираме нашите тестове с jacoco: dump като цел, за да инициираме заявка за изхвърляне.

Можете да проследите връзката на официалната документация за по-задълбочени подробности относно дизайна на JaCoCo.

6. Резултат за покритие на кода

Сега, след като знаем малко за това как работи JaCoCo, нека подобрим нашия рейтинг за покритие на кода.

За да постигнем 100% покритие на кода, трябва да въведем тестове, които покриват липсващите части, показани в първоначалния доклад:

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

Сега можем да кажем, че имаме достатъчно тестове, за да покрием целия си код, но за да се уверим в това, нека стартираме командата Maven mvn jacoco: report, за да публикуваме отчета за покритието:

Както можете да видите, всички редове / клонове / пътеки в нашия код са изцяло покрити:

В реалния свят и с напредването на развитието трябва да следим резултата за покритие на кода.

JaCoCo предлага прост начин за деклариране на минимални изисквания, които трябва да бъдат изпълнени, в противен случай компилацията ще се провали.

Можем да направим това, като добавим следната цел за проверка в нашия файл pom.xml :

 jacoco-check  check     PACKAGE   LINE COVEREDRATIO 0.50      

Както вероятно се досещате, тук ограничаваме минималния резултат за покритие на линиите до 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.

Можете да проверите примера, предоставен в тази статия в свързания проект GitHub .