Comments 32
Но статья отличная, спасибо за линк.
Например, 'commited by Vasya, «Will test later, deadline»'. Или проекты где анализ внедряется после 5 лет разработки: в наличии миллион строк кода, покрытие — 50%. Метить непокрытый код проблемно, придется реагировать на изменения.
Но в целом вариант очень даже интересный, с явными преимуществами перед 80% покрытия.
Если не гнаться за цифрами, то это не метрика.
Обычно ведь покрытие тестами кода должно говорить не то, что код покрыт на 60%, а то, что в 40% кода тесты вообще не смогли зайти. Или по-другому: разработчик не способен написать такие интеграционные или модульные тесты, которые бы зашли в эти 40% (за приемлемое время).
То есть правильная характеристика — не покрытие кода, а скорее "мера непокрытого кода".
Ну и конечно — адекватность тестов должна проверяться отдельно на code review, тут уже никто не спорит. Накрутки тестов и покрытие должны исключаться и удаляться.
Code Review позволяет прикинуть какие сценарии коммитер протестировал, но только прикинуть. CC инструмент же заодно подсвечивает те строки метода, которые не покрыты.
Несомненно, предварительный просмотр кода CC утилитой не отменяет CodeReview, однако и CodeReview предварительного просмотра полностью не заменит.
Не забывайте что есть другие подходы, например Property Based Testing или Mutation Testing, которые друг друга дополняют и могут заменить классический ААА путь написания тестов. Но защиты от сумасшедшего индуса дурка нет.
Пример:
if(a > 5){
…
} else {
…
}
Вы пишете тест где а = 10 и а = 3. Анализ покрытия скажет вам, что код протестен на 100%. Но говорит ли этот факт о том, что условие действительно корректно протестено? Конечно нет, ибо если вдруг поменяем условие на а >=5 тесты все еще будут зелеными, хотя поведение программы изменилось.
Поэтому можно говорить только о том, что покрытие в 70% наверное лутше чем в 50% и не более того.
Что бы улутшить ситуацию, надо тестить сами тесты. Например через mutation testing. На хабре есть статьи на эту тему, очень рекомендую.
Анализ покрытия скажет вам, что код протестен на 100%
Это необразованный человек так интерпретирует результаты анализатора. Анализ покрытия говорит, что все ветки кода исполнялись хотя бы раз. Ничего более.
Вы пишете тест где а = 10 и а = 3.
Наш код стоит тестировать примерами a=5 и a=4, как два граничных случая. Соответственно, появится красный тест при изменении условия на a >= 5.
Любой процент ппокрытия не говорит вообще ничего, потому что эта метрика никак не связана с качеством тестов.
Вы несколько категоричны. Метрика действительно может иметь расхождение с качеством приложения\тестов, однако она предоставляет первичную оценку, что уже неплохо. Иначе бы CC не использовали. Плюс, CC — это не только метрика. В случае .NET есть CC утилита, подсвечивающая посещенные\непосещенные тестами куски кода, что весьма помогает при написании тестов.
Что до мутационного тестирования — это (интересная) тема отдельных статей на хабре.
Нужно ли мерить покрытие кода авто-тестами? Мое мнение — обязательно. И в первую очередь не ради магической цифры, а для анализа результатов.
Да, как и любую другую метрику ее можно скомпрометировать.
Да, метрика является линейной — не может отличить полезный код от мало- или бесполезного. Но если фокусироваться на анализе, то смотреть можно на покрытие отдельных компонент или библиотек. При желании можно как-то разметить код и получить нелинейную метрику (примерно как раскладка багов по северити).
Да, метрика не показывает отсутствующие ветки кода или покрытие граничных условий. Примите как ограничение. Покрытие требований избавлено от этих недостатков? Вы все граничные условия прописываете в требования?
Я бы выделил следующие сильные стороны измерения и анализа покрытия кода по сравнению с покрытием требований:
1. тестовое покрытие можно мерить при отсутствии требований или других артефактов.
2. метрика инструментальная, т.е. ее получение обычно относительно недорого (в плане трудозатрат).
3. Т.ч. процесс измерений автоматизирован, то исключен человеческий фактор — труднее манипулировать результатом.
4. Т.к. процесс относительно дешев, то можно мерить часто и отслеживать тренды.
И если смотреть на тренды, а не на абсолютные цифры, то легко ответить на данные вопрос " Нужно ли покрывать мертый код?" — Нет, не нужно. Если он реально мертвый, то нужно выбросить. Если он редкоиспользуемый и мы не хотим его покрывать, но тренд все равно будет растущий (при условии, что новый код покрыт на достаточном уровне).
И опять же, любую полезную метрику можно превратить во вредный KPI, т.ч. я бы не стал на этом моменте фокусироваться. Гораздо интереснее сопоставлять сильные и слабые стороны разных метрик оценки тестового покрытия.
СС — это технологическая метрика. Она не много говорит о качестве программного продукта. Зато кое-что говорит о качестве процесса его разработки!
Спасибо!
Пример:
Предположим, на следующий год вы можете влиться в одну из двух команд.
Всё примерно одинаково: по 4 человека в командах, тип приложения в обоих случаях "как вы любите", размеры исходного кода, количество пользователей, выручка… всё примерно одинаково.
Но в одном случае у проекта на дашборде светится 62.4% code coverage (а на начало прошлого года — 55%), а у другого проекта этой цифры вообще нет и никто даже примерно ее не знает.
В какую команду вы пойдете?
В какую команду вы пойдете?
Во вторую (если они готовы к нововведениям).
У них есть очевидные резервы для улучшения, а значит и пользователей с выручкой можно будет нарастить проще и быстрее.
Первые же, несмотря на более тщательный контроль качества не смогли оторваться по ключевым параметрам, а значит их проблемы могут быть куда серьезнее, чем отсутствие контроля метрики качества кода.
А разработчикам посоветовал бы идти в первую. Т.к. по моим внутренним убеждениям, при прочих равных она выиграет в долгосрочной перспективе. Технический долг сказывается на дистанции, я бы предположил, что во второй команде он выше.
На мой взгляд создатели Agile-манифеста вполне исчерпывающе высказались на эту, и похожие темы.
(поскольку создана для Васи, который будет её юзать через два дня).
А почему юнит тест не может это покрыть?
Практика не самая лучшая, мало отличается от мертвого кода, но изредка допустима.
Иногда у меня в таких приватных методах зашиты исключения на тот случай, если кто-либо когда-либо попробует-таки использовать метод неправильно. То есть, все текущие методы используют приватный метод корректно, но в теории кто-то может и косякнуть в будущем. Также довольно спорная практика, однако в ядре приложения иногда спокойнее перестраховаться.
Если это большой метод, то почему нельзя его вынести в отдельный класс или написать test-specific descendant для тестирования или сделать публичным, если это маленький метод почему нельзя чтобы коллега его добавил при разработке.
Остальные сценарии (перенести в класс, сделать публичным, оставить Васе) тоже имеют право на жизнь, однако могут привнести свои сложности.
В итоге мы получим некоторое количество геморроя лишь для «100% покрытия».
Возвращаясь к оригинальной фразе (часть кода… недостижима (поскольку создана для Васи, который будет её юзать через два дня).) — вы правы, с недостижимостью я косякнул.
Наличие на предприятии директора по качеству, ОТК и сертификатов качества, еще не говорит, что продукт качественный(директор — разгильдяй, сертификаты липовые), но по крайней мере на этом заводе знают слово «качество»)))
Для меня тесты — это не только показатель работоспособности кода, но и инструмент для написания более архитектурно грамотного, качественного кода. Следуя TDD проблемные места видны заранее, еще до того как был реализован класс.
По этой причине низкое покрытие тестами может быть сигналом о том, что присутствуют архитектурные проблемы. На практике я заметил, что практически всегда тот код, который нельзя/сложно протестировать — код низкого качества.
Поэтому я стараюсь достигать как можно больших значений CC, пытаясь не "читерить".
Code Coverage — хочу верить