Nikita Koliadin
40 уровень

Code Coverage

Статья из группы Random
участников
Приветствую, друзья, коллеги и... пингвины! Code Coverage - 1Сегодня мы поговорим о Code Coverage, разберемся что это, зачем он нужен и как прокачать свой open-source project предоставив статистику Code Coverage. Эта статья является лаконическим продолжением предыдущей об Continuous Integration. Здесь мы узнаем еще одно сильное преимущество CI в сочетании с... а скоро узнаете с чем сами! Подчеркну лишь то, что здесь не будет указаний как правильно писать тесты для своих программ, и как добиваться максимально возможного полезного покрытия, этот весь грех останется лишь на ваших плечах. Итак, погнали!

Что такое Code Coverage?

Code Coverage (покрытие кода) - это некая величина, показывающая нам процент выполненного исходного кода, во время тестирования. Окей, тут вроде бы всё ясно. Процент Code Coverage (покрытие кода, дальше просто CC) может колебаться от 0 до 100, и может возникнуть вопрос, нужно ли стремиться к максимальному проценту CC? Мой ответ таков: и да и нет. Почему так? Допустим вы создаете проект который будет использоваться некими другими проектами, в нем полно функционала, и среди всего ужаса есть геттеры и сеттеры, и их не мало. При покрытии функционала покрылись не все, допустим, геттеры, но вы точно знаете, что те, которые не покрылись, и не вызываются в вашем проекте, но геттеры не всегда пишутся "для себя", поэтому они нужны для "клиента". Что же делать? Покрыть каждый геттер отдельно? Это будет не эффективное тестирование. Но если не покрыть их, мы не добьемся максимального процента CC. Здесь возникает палка двух концов.

Зачем нам нужно Code Coverage?

Я думаю на этот вопрос ответ будет очень прост: Любой код нуждается в тестировании, дабы при рефакторинге либо при добавлении/изменении функционала не возникли "невидимые" баги, и мы их могли отследить. Не будем же мы бегать по фреймворкам с breakpoint и дебаггером и ловить этого подлого БаГа. Жизнь слишком коротка. Пример Итак, самое интересное. Задача такова: Внедрить в наш open-source project, который мы написали на предыдущей статье, технологию, которая будет собирать информацию о CC, обрабатывать где-то ее, и будет возможность поместить эту информацию у себя на GitHub в форме бейджика, например. Все исходные кода будут выложены на моем GitHub.
  1. Начнем с выбора плагина для сборки информации о покрытии кода в одну кучу. Я лично для себя выбрал JaCoCo, который как раз таки собирает информацию о покрытии кода. Но есть и альтернативы.

    Сайт JaCoCo предлагает нам скачать плагин, но качать мы нечего не будем, ведь мы используем Build System Maven. Заходим в Maven Repository и ищем JaCoCo Plugin. Берем последнюю версию, и вставляем в наш pom.xml зависимость.

    Но через dependencies я делать не рекомендую, ведь есть более хороший, более функциональный альтернативный вариант, и даже не один.

    1. Заходим CodeCov Setup выбираем язык Java и выбираем Using JaCoCo плагин, и ставим по инструкции.

    2. По той же ссылке выбираем Using Maven. Этот вариант будет даже лучше. Cobertura будет извлекать информацию из CI тестов, но увы и тут есть подвох. Все что выше JDK 7 (А на данный момент уже 10 есть) не подойдет. Поэтому мы остановимся на 1 варианте.

    В результате в нашем pom.xml должно было появиться что то вроде того:

    <!-- JaCoCo plugin -->
    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.1</version>
        <executions>
            <execution>
                <goals>
                    <goal>prepare-agent</goal>
                </goals>
            </execution>
            <execution>
                <id>report</id>
                <phase>test</phase>
                <goals>
                    <goal>report</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

    И в Maven Projects в списке плагинов появится JaCoCo Plugin:

    Code Coverage - 2
  2. Плагин стоит. Все вроде бы замечательно. Но если вы внимательно читали инструкцию по установке JaCoCo плагина, там было указание, добавить в .travis.yml строчку, отвечающую за отправку отчёта плагина на сайт Codecov.

    Итак, исходя из Using JaCoCo, нам нужно вписать в наш файл:

    after_success:
      - bash <(curl -s https://codecov.io/bash)

    Вписали. Отлично.

  3. Все вроде готово, и остались финальные штрихи. Во-первых давайте скомпилируем наш код, и запустим все тесты, причем сделаем это через Lifecycle Maven:

    Code Coverage - 3

    Так как у нас в плагине JaCoCo стоит фаза выполнения test, то должен был появится отчет после выполнения цикла тестов Maven в папке target:

    Code Coverage - 4
  4. Подходим к завершению. Мы видим что все работает прекрасно, осталось лишь убедится что это "все прекрасно" также будет работать на внешних источниках. Настала пора собрать все в кучу. Собираем проект и делаем push на GitHub, перед этим открыв Travis CI и Codecov для мониторинга происходящего.

    После push мы видим что сборка успешная:

    Code Coverage - 5

    И результат JaCoCo плагина о покрытии кода:

    Code Coverage - 6
  5. Помните нашу задачу? Да, да, мы забыл про бейджик. Я хотел вынести тему "Украшение" open-source project'ов в отдельную статью, но маленькую часть все же оставлю здесь.

    Итак, пошаговая инструкция что бы не заблудится:

    1. Переходим на сайт Codecov;

    2. Выбираем проект, который вам нужно;

    3. Выбираем Setting:

      Code Coverage - 7
    4. Выбираем Badge и видим ссылки на ваш бейджик в несколько различных формах представления:

      Первые это стандартные бейджики, их можно вставить, например, в ваш README.md:

      Code Coverage - 8

      Их особенность в том что при кликании на них вас будет перенаправлять на страницу с отчетом о CC;

      Вторые это графы, таблицы и тому подобные штуки:

      Code Coverage - 9
Полезные ссылки Могут быть ошибки, ОтЧиПяТкИ в тексте. Всем спасибо за внимание!
Комментарии (8)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Игорь
Уровень 40
13 февраля 2019, 13:26
Разобрался. Не в тот файл смотрел просто :) Я смотрел в jacoco.exec (он да, он не меняется), а все изменения происходят с target/site/jacoco/ В итоге правильный рабочий вариант:
<!-- JaCoCo plugin -->
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco-version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    <configuration>
                        <excludes>
                            <exclude>**/Application.class</exclude>
                        </excludes>
                    </configuration>
                    </execution>
                </executions>
            </plugin>
Игорь
Уровень 40
7 февраля 2019, 10:20
У кого-то есть опыт исключения отдельных классов из финального репорта с помощью мавена? Все примеры что находил в интернете были либо для гредла (на проекте не используется), либо давало на выходе 0% code coverage для исключенных классов(что порой только хуже). На гитхабе jacoco в комментариях годовалой давности упоминалось что это баг и не понятно пофиксили ли его (версию выше 0.8.0 использовать проблематично). Если у кого-то есть рабочий пример буду признателен. Заранее спасибо. Мой вариант конфигурации (который дает 0% code coverage для Application.class):
<!-- JaCoCo plugin -->
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco-version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <excludes>
                        <exclude>**/Application*</exclude>
                    </excludes>
                </configuration>
            </plugin>
iOSif_StyleIN Android Developer в Уральский процессинг
5 октября 2018, 09:30
а для Андроид пойдёт?
Igor Vlasuyk
Уровень 18
19 сентября 2018, 10:29
Есть ли возможность использовать Jacoco для оценки покрытия тестами, в случае когда репозиторий проекта и репозиторий автотестов для этого проекта разделены между собой, т.е. по сути это два разных проекта?
Nikita Koliadin Full Stack Developer в Приватбанк
21 сентября 2018, 10:36
Смотря как разделены. Если вы имеете в виду что это разные модули - тогда да. Многомодульный мавен это позволит сделать. Если это абсолютно два разных проекта, тогда нужно задуматься как сделать так, что бы ваш проект с тестами был доступен в вашем проекте с исходным кодом.
Nikita Koliadin Full Stack Developer в Приватбанк
1 мая 2018, 14:28
Добавил завершающую статью!
Евгений Гродно
Уровень 36
Expert
1 мая 2018, 03:14
Очень круто, нужно брать ;)
Nikita Koliadin Full Stack Developer в Приватбанк
1 мая 2018, 09:12
Спасибо!)