Вступ до 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 та switch .
  • Цикломатична складність відображає складність коду, надаючи кількість шляхів, необхідних для охоплення всіх можливих шляхів у коді за допомогою лінійної комбінації.

Візьмемо тривіальний приклад: якщо в коді немає операторів if або switch , цикломатична складність буде 1, оскільки нам потрібен лише один шлях виконання, щоб покрити весь код.

Як правило, цикломатична складність відображає кількість тестових випадків, які нам потрібно виконати, щоб охопити весь код.

5. Розбиття концепції

JaCoCo працює як агент Java , він відповідає за тестування байт-коду під час запуску тестів. 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 .