Введение в JaCoCo

1. Обзор

  • Покрытие кода ** - это метрика программного обеспечения, используемая для измерения количества строк нашего кода, выполняемых во время автоматических тестов.

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

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

Чтобы начать работу с JaCoCo, нам нужно объявить этот https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.jacoco%22%20AND%20a%3A% 22jacoco-maven-plugin% 22[плагин maven]в нашем файле pom.xml :

<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>

Ссылка, предоставленная здесь и раньше, всегда приведет вас к последней версии плагина в центральном репозитории 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.

Очевидно, что мы не можем интерпретировать вывод в одиночку, но другие инструменты и плагины могут - например,

Хорошей новостью является то, что мы можем использовать цель jacoco: report , чтобы создавать читаемые отчеты о покрытии кода в нескольких форматах - например, HTML, CSV и XML.

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

Изображение:/uploads/coverage-3.png[покрытие]

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

Изображение:/uploads/palindrometest1-1.png[изображение, ширина = 644, высота = 232]

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

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 Interface в процессе:

концепция jacoco

Также возможно запустить агент JaCoCo в режиме сервера, в этом случае мы можем запустить наши тесты с jacoco: dump в качестве цели, чтобы инициировать запрос дампа.

Вы можете перейти по ссылке official context для документов для получения более подробной информации о дизайне 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 , чтобы опубликовать отчет о покрытии:

Изображение:/uploads/coverage-2.png[покрытие]

Как вы можете видеть, все строки/ветви/пути в нашем коде полностью покрыты:

Изображение:/uploads/coverage-1.png[покрытие]

В реальных проектах и ​​по мере развития событий мы должны следить за показателями покрытия кода.

JaCoCo предлагает простой способ объявления минимальных требований , которые должны быть выполнены, иначе сборка не удастся.

Мы можем сделать это, добавив следующую цель check в наш файл pom.xml :

<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>

Как вы, вероятно, можете догадаться, мы ограничиваем здесь минимальный показатель для покрытия линий до 50%.

Цель jacoco: check привязана к verify , поэтому мы можем запустить команду Maven - mvn clean verify , чтобы проверить, соблюдаются ли правила или нет. Журналы покажут что-то вроде:

----[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. Заключение

В этой статье мы увидели, как использовать плагин JaCoCo maven для генерации отчетов о покрытии кода для проектов Java.

Имейте в виду, однако, что 100% покрытие кода не обязательно отражает эффективное тестирование , поскольку оно отражает только объем кода, использованного во время тестов. В предыдущей статье мы говорили о mutation testing как о более сложном способе отслеживания эффективности тестов по сравнению с обычным охватом кода .

Вы можете ознакомиться с примером, приведенным в этой статье, по ссылке проект GitHub