Сегодня та или иная библиотека на Github, у которой нет тестов, уже не воспринимается серьезно. Тесты помогают нам смело делать рефакторинг и быть уверенными, что модуль, класс или функция работают так, как это задумывалось. Они позволяют нам тестировать наш код на разных версиях PHP и выявлять ошибки заранее. Это гарант качества и стабильности вашего кода.
Стремиться к стопроцентному покрытию кода нет никакого смысла, однако понимать в среднем какой процент кода покрыт вашими тестами — хорошая метрика при непрерывном интегрировании.
Мы можем настроить оповещения при падении процента покрытия, например, ниже 50, можем добавлять автоматические комментарии от ботов в пул реквестах, показывать тенденцию изменения Code Coverage на графиках с течением времени и т.д.
Но что делать, если вы используете несколько библиотек для тестирования? Как получить общее покрытие кода?
Тут на помощь приходит библиотека phpcov
Итак, что мы будем делать при каждом билде (на примере Travis-CI):
Для примера, возьмем проект на Symfony3, где используются PHPUnit совместно с phpspec.
Конфигурация тестов PHPUnit может выглядеть следующим образом:
Это стандартный конфиг, за исключением нескольких строк:
Здесь мы говорим, что будет использован PHP формат отчета о покрытии и кладем файл в нужную папку.
Далее похожие действия делаем с phpspec:
Осталось запустить это всё дело при каждом билде и смержить результаты:
phpcov собирает все данные из вашей папки, объединяет их и сохраняет результат в формате Clover, который можно использовать для отображения покрытия кода, в том числе, и такого бейджа
Вот и всё. Пишите тесты, рефакторите с удовольствием.
UPD: бейджи, комментарии в пул реквестах и многое другое делается с помощью сервиса codecov.io (или как альтернатива — coveralls.io)
После настройки репозитория, интеграция с Travis-CI делается в одну строку:
Codecov автоматически возьмет сгенерированный отчет в формате Clover и проанализирует его.
Также, при установке дополнения в браузер, можно прямо на Github видеть, какие строки покрыты тестами, а какие нет:
Стремиться к стопроцентному покрытию кода нет никакого смысла, однако понимать в среднем какой процент кода покрыт вашими тестами — хорошая метрика при непрерывном интегрировании.
Мы можем настроить оповещения при падении процента покрытия, например, ниже 50, можем добавлять автоматические комментарии от ботов в пул реквестах, показывать тенденцию изменения Code Coverage на графиках с течением времени и т.д.
Но что делать, если вы используете несколько библиотек для тестирования? Как получить общее покрытие кода?
Тут на помощь приходит библиотека phpcov
Итак, что мы будем делать при каждом билде (на примере Travis-CI):
- Запускаем тесты PHPUnit, генерируем Code Coverage
- Запускаем тесты phpspec, генерируем Code Coverage
- Объединяем (merge) полученные результаты в единое покрытие
- Сохраняем результаты для последующего анализа и отображения
Для примера, возьмем проект на Symfony3, где используются PHPUnit совместно с phpspec.
Конфигурация тестов PHPUnit может выглядеть следующим образом:
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="app/autoload.php"
>
<php>
<ini name="error_reporting" value="-1" />
<server name="KERNEL_DIR" value="app/" />
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src</directory>
<exclude>
<directory>src/*Bundle/Resources</directory>
<directory>src/*/*Bundle/Resources</directory>
<directory>src/*/Bundle/*Bundle/Resources</directory>
</exclude>
</whitelist>
</filter>
<logging>
<log type="coverage-php" target="/tmp/coverage_phpunit.cov"/>
</logging>
</phpunit>
Это стандартный конфиг, за исключением нескольких строк:
<logging>
<log type="coverage-php" target="/tmp/coverage_phpunit.cov"/>
</logging>
Здесь мы говорим, что будет использован PHP формат отчета о покрытии и кладем файл в нужную папку.
Далее похожие действия делаем с phpspec:
# phpspec.yml
...
extensions:
PhpSpecCodeCoverage\CodeCoverageExtension:
format:
- php
output:
php: /tmp/coverage_phpspec.cov
Осталось запустить это всё дело при каждом билде и смержить результаты:
# .travis.yml
...
script:
- bin/phpspec run --format=pretty
- bin/phpunit
- wget https://phar.phpunit.de/phpcov.phar && php phpcov.phar merge /tmp --clover coverage.xml
phpcov собирает все данные из вашей папки, объединяет их и сохраняет результат в формате Clover, который можно использовать для отображения покрытия кода, в том числе, и такого бейджа
Вот и всё. Пишите тесты, рефакторите с удовольствием.
UPD: бейджи, комментарии в пул реквестах и многое другое делается с помощью сервиса codecov.io (или как альтернатива — coveralls.io)
После настройки репозитория, интеграция с Travis-CI делается в одну строку:
# .travis.yml
...
after_success:
- bash <(curl -s https://codecov.io/bash)
Codecov автоматически возьмет сгенерированный отчет в формате Clover и проанализирует его.
Также, при установке дополнения в браузер, можно прямо на Github видеть, какие строки покрыты тестами, а какие нет:
Поделиться с друзьями
Комментарии (7)
Alex_T666
28.11.2016 13:47+1Сегодня та или иная библиотека на Github, у которой нет тестов, уже не воспринимается серьезно.
Кем не воспринимается? Значит ли это, что тесты должны быть в любой библиотеке, просто «шоб було»?
Тесты помогают нам смело делать рефакторинг и быть уверенными, что модуль, класс или функция работают так, как это задумывалось. Они позволяют нам тестировать наш код на разных версиях PHP и выявлять ошибки заранее. Это гарант качества и стабильности вашего кода.
Это если сами тесты написаны правильно. А кто будет гарантировать качество самих тестов? Тесты тоже пишутся людьми и само по себе их наличие, не дает никакой гарантии качества и стабильности кода. Тем более, что «Стремиться к стопроцентному покрытию кода нет никакого смысла», это означает, что кто-то решает что покрыть тестами, а что — нет. Всегда ли это решение разумно и обосновано?VolCh
01.12.2016 11:38+1Наличие тестов, проходящих мало-мальское код-ревью (просто чтобы убедиться, что они реально что-то тестируют) или просто автоматически полученная метрика покрытия, близкая к 100%, уменьшает вероятность ошибки. Грубо, если я делаю одну ошибку на 10 строк кода случайным образом, то проходящие тесты дают основание считать, что в основном коде остались ошибки в одной строке из 100. Это не гарантия, конечно, но статистико-вероятностная оценка количества ошибок.
borNfree
28.11.2016 13:54Кем не воспринимается? Значит ли это, что тесты должны быть в любой библиотеке, просто «шоб було»?
Не воспринимается разработчиками. Если я вижу выбор среди нескольких бандлов/модулей, не последнее место будет занимать критерий выбора по наличию test suite.
Да что тут говорить, когда делаешь PR тебя в большинстве случаях попросят добавить и тесты, хотябы как самый свежий пример — изменение в этом плане политики в репозитории Yii фреймворка.
А кто будет гарантировать качество самих тестов? Всегда ли это решение разумно и обосновано?
Мне кажется, вы придираетесь к словами. Когда вы пишите тесты, вы часто находите ошибки в своем коде (если пишите их после написания кода). Либо тесты помогают вам изначально выстроить более лучшую архитектуру ваших классов, если вы пишите тесты до написания кода. Естественно могут быть ошибки и в тестах, это очевидно.
Еще раз подчеркну, тесты гарантируют вам что после рефакторинга ваш код работает так, как вы это задумывали до него. Меньше траты времени на поддержку -> меньше багов -> более стабильный код
AlexLeonov
Самое интересное и не рассказали — как бейджик сделать? ))
zviryatko
https://coveralls.io/ — тут есть инструкция.
AlexLeonov
Спасибо. Думал, что это бейджик от Travis, но там такого не нашел.
borNfree
добавил в статью еще альтернативный вариант