Каков разумный охват кода% для модульных тестов (и почему)? [закрыто]

605

Если бы вы указали минимальный процент покрытия кода для модульных тестов, возможно, даже в качестве требования для фиксации в хранилище, что бы это было?

Пожалуйста, объясните, как вы пришли к своему ответу (поскольку, если бы вы только выбрали номер, я мог бы сделать это сам;)

вменяемость
источник
Теперь многие IDE приходят с подсветкой покрытия, убедитесь, что вы охватили самые важные части кода, по крайней мере, чем думаете о достижении определенного процента.
Всех с нетерпением
4
Символ% - это запах кода для метрик (в общем,% - это дерьмовый запах)
Эрнан Эче
Модульные тесты по определению могут быть отдельными методами, целыми классами или целыми модулями. Даже если вы протестируете все методы, вы можете не протестировать все пути или все комбинации, которые попадет пользователю. Ситуация усложняется с заявлениями, охватом филиалов и MCDC.
Ска
Почему этот вопрос не удален или не отредактирован? Он вызвал такой большой интерес, но это вводит в заблуждение.
Ска

Ответы:

1391

Эта проза Альберто Савойя отвечает именно на этот вопрос (очень интересно!):

http://www.artima.com/forums/flat.jsp?forum=106&thread=204677

Тестус на тестовом покрытии

Рано утром программист спросил великого мастера:

«Я готов написать несколько юнит-тестов. На какой охват кода я должен стремиться? »

Великий мастер ответил:

«Не беспокойтесь о покрытии, просто напишите несколько хороших тестов».

Программист улыбнулся, поклонился и ушел.

...

Позже в тот же день второй программист задал тот же вопрос.

Великий мастер указал на кастрюлю с кипящей водой и сказал:

«Сколько зерен риса я должен положить в этот горшок?»

Программист, выглядя озадаченным, ответил:

«Как я могу вам сказать? Это зависит от того, сколько людей вам нужно накормить, насколько они голодны, какую другую пищу вы подаете, сколько риса у вас есть и так далее ».

«Точно», сказал великий мастер.

Второй программист улыбнулся, поклонился и ушел.

...

В конце дня пришел третий программист и задал тот же вопрос о покрытии кода.

«Восемьдесят процентов и не меньше!» - ответил мастер строгим голосом, стуча кулаком по столу.

Третий программист улыбнулся, поклонился и ушел.

...

После этого последнего ответа молодой ученик подошел к великому мастеру:

«Великий мастер, сегодня я слышал, как вы ответили на один и тот же вопрос о покрытии кода тремя разными ответами. Почему?"

Великий мастер встал со стула:

«Пойдемте со мной свежий чай и поговорим об этом».

После того, как они наполнили свои чашки горячим зеленым чаем, великий мастер начал отвечать:

«Первый программист новый и только начинает тестирование. Сейчас у него много кода и нет тестов. Ему предстоит долгий путь; сосредоточение внимания на покрытии кода в это время было бы удручающим и совершенно бесполезным. Ему лучше просто привыкнуть к написанию и проведению некоторых тестов. Он может беспокоиться о покрытии позже.

«Второй программист, с другой стороны, имеет большой опыт в программировании и тестировании. Когда я ответил ей, спросив, сколько зерен риса я должен положить в горшок, я помог ей понять, что количество необходимых испытаний зависит от ряда факторов, и она знает эти факторы лучше, чем я, - в конце концов, это ее код. , Единого простого ответа не существует, и она достаточно умна, чтобы справиться с истиной и работать с этим ».

«Понятно, - сказал молодой ученик, - но если нет единого простого ответа, то почему вы ответили третьему программисту:« Восемьдесят процентов и не меньше »?»

Великий мастер смеялся так сильно и громко, что его живот, свидетельствующий о том, что он пил больше, чем просто зеленый чай, шлепнулся вверх и вниз.

«Третий программист хочет только простые ответы - даже если нет простых ответов… и тогда все равно не следует им».

Молодой ученик и седой великий мастер закончили пить чай в задумчивой тишине.

Джон Лимджап
источник
62
Звучит как аргумент против общей концепции покрытия кода, как метрика для оценки полезности модульных тестов. Я уверен, что все согласны с тем, что это не идеальный показатель, но личный опыт, как мы надеемся, должен показать некоторую корреляцию между CC% и эффективностью модульного теста ...
здравомыслие,
16
здравомыслие - ваше высказывание точно отражено в ответе «второму разработчику». Личный опыт должен диктовать это.
Джон Лимджап
167
Идеальный ответ. Метрики не делают хороший код. Вы можете написать дрянной код со 100% покрытием, и это не делает код работоспособным. +1 от меня, позор, я не могу подняться больше :)
Роб Купер
15
4 года спустя и до сих пор полезно. Только что вытащил это на двух моих коллег этим утром.
SickHippie
9
Для меня этот анекдот представляет идеалистический взгляд. В реальном мире проектных команд с конкурирующими приоритетами покрытие кода возрастает до 0%. Нам нужно необходимое число, чтобы выстроить в команде привычку к тестированию модулей. Я пришел к этому вопросу в поисках руководства по определению этого числа для области, с которой я не очень хорошо знаком, и это на самом деле не помогает. Я рад, что люди в других сценариях находят это полезным, хотя.
samspot
86

Покрытие кода - это вводящий в заблуждение показатель, если ваша цель - охват 100% (вместо 100% тестирования всех функций).

  • Вы можете получить 100%, ударив по всем линиям один раз. Однако вы все равно можете пропустить тестирование определенной последовательности (логического пути), в которой эти строки попадают.
  • Вы не могли получить 100%, но все же проверили все ваши 80% / freq используемые пути кода. Наличие тестов, которые проверяют каждый «бросок ExceptionTypeX» или подобную защиту защитного программирования, которую вы вставили, - это «хорошо иметь», а не «иметь»

Так что доверяйте себе или своим разработчикам быть внимательными и охватывать каждый путь через их код. Будьте прагматичны и не гонитесь за магическим 100% покрытием. Если вы TDD свой код, вы должны получить 90% + покрытие в качестве бонуса. Используйте покрытие кода, чтобы выделить фрагменты кода, который вы пропустили (хотя этого не должно произойти, если вы используете TDD… поскольку вы пишете код только для прохождения теста. Никакой код не может существовать без теста партнера)

Gishu
источник
4
- Исключения - если вы не проверяете обработку исключений, откуда вы знаете, что ваш код не взрывается, когда это происходит? - Сеттеры / геттеры - я полагаю, что это зависит от контекста, но наверняка ваши тесты должны выполнять их как часть набора тестов, и если они этого не делают, они действительно используются?
tddmonkey
1
Исключения должны быть исключительными - не должно происходить. Если они это сделают, вы регистрируете точку отказа и залог. Вы не можете проверить каждое исключение, которое может произойти. Если приложение должно обрабатывать не счастливый путь / событие, вы должны иметь тест для него. Средства доступа могут быть добавлены для будущих клиентов .. зависит
Gishu
5
Я не уверен, что вы подразумеваете под своим вторым пунктом "но все же проверили все ваши пути кода". Если вы на самом деле имеете в виду покрытие полного пути, то нет, вы не можете иметь покрытие полного пути без 100% покрытия линии / ответвления / решения. Фактически, покрытие полного пути обычно недоступно в любой нетривиальной программе из-за комбинаторного характера ветвей в генерирующих путях. en.wikipedia.org/wiki/Code_coverage#Other_coverage_criteria
Зак Burlingame
3
Вы не проверяете все возможные исключения; Конечно, вы не можете этого сделать. Вы ДОЛЖНЫ стремиться протестировать каждый блок кода, который обрабатывает исключения. Например, если у вас есть требование, чтобы, когда блок X генерировал исключение, это исключение регистрировалось в базе данных, зеленая полоса внизу экрана становилась красной, и папе отправлялось электронное письмо; тогда это то, что вы должны проверить. Но вам не нужно проверять каждое возможное исключение, которое может вызвать эти события.
Дауд ибн Карим
2
+1 за «Использование покрытия кода для выделения фрагментов кода, которые вы пропустили». Это в основном то, для чего хорош этот показатель.
белучин
61

Покрытие кода отличное, но функциональность еще лучше. Я не верю в освещение каждой отдельной строки, которую я пишу. Но я верю в написание 100% тестового покрытия всей функциональности, которую я хочу предоставить (даже для дополнительных классных функций, которые я пришел с собой и которые не обсуждались во время встреч).

Мне все равно, будет ли у меня код, который не описан в тестах, но мне было бы интересно, если бы я реорганизовал свой код и в конечном итоге имел другое поведение. Поэтому 100% функциональность - моя единственная цель.

tofi9
источник
4
Это фантастический ответ. Код, который соответствует его требованиям, является гораздо более стоящей целью, чем код, который соответствует некоторой произвольной метрике покрытия LoC.
Дауд ибн Карим
46
Если вы можете предоставить все функциональные возможности, не затрагивая все строки кода, то что эти дополнительные строки кода там делают?
Дженс Тиммерман
4
@JensTimmerman теоретически ты прав. Однако покрытие кода на 100% слишком дорого по времени, и вынуждает мою команду это не только демотивировать, но и заставляет мой проект работать в срок. Мне нравится быть где-то посередине, и тестирование функциональности (назовите это: интеграционное тестирование) - это то, с чем я чувствую себя комфортно. Какой код я не тестирую? Техническая обработка исключений, (диапазон / параметр) проверки, которые могут потребоваться. Короче говоря, вся техническая сантехника, которую я научился применять из собственного опыта или лучших практик, о которых я читал.
Тофи9
2
Я сделал еще один шаг вперед, составив список распространенных ситуаций, которые следует включить или исключить из тестирования. Таким образом, мы никогда не стремились к проценту, а скорее к функциональному охвату всех частей рабочей кодовой базы.
Skeeterdrums
58

Принятый ответ имеет смысл: нет ни одного числа, которое будет иметь смысл в качестве стандарта для каждого проекта. Есть проекты, которым просто не нужен такой стандарт. На мой взгляд, не хватает принятого ответа в описании того, как можно принять это решение для данного проекта.

Я сделаю снимок при этом. Я не эксперт по тестированию и был бы рад получить более информированный ответ.

Когда устанавливать требования к покрытию кода

Во-первых, почему вы хотите навязать такой стандарт в первую очередь? В общем, когда вы хотите внести эмпирическую уверенность в свой процесс. Что я имею в виду под «эмпирической уверенностью»? Ну, настоящая цель - правильность . Для большинства программного обеспечения мы не можем знать это по всем входам, поэтому мы согласны с утверждением, что код хорошо протестирован . Это более понятно, но все же это субъективный стандарт: он всегда будет открыт для дебатов о том, встречали ли вы его или нет. Эти дебаты полезны и должны произойти, но они также показывают неопределенность.

Покрытие кода является объективным измерением: как только вы видите свой отчет о покрытии, нет никакой двусмысленности относительно того, были ли соблюдены стандарты, полезны. Это доказывает правильность? Вовсе нет, но он имеет четкое отношение к тому, насколько хорошо протестирован код, что, в свою очередь, является нашим лучшим способом повысить уверенность в его правильности. Покрытие кода - это измеримое приближение неизмеримых качеств, которые нас интересуют.

Некоторые конкретные случаи, когда наличие эмпирического стандарта может добавить ценность:

  • Для удовлетворения заинтересованных сторон. Для многих проектов есть разные действующие лица, заинтересованные в качестве программного обеспечения, которые могут не участвовать в повседневной разработке программного обеспечения (руководители, технические руководители и т. Д.). Сказав: «Мы собираемся написать все «Тесты, которые нам действительно нужны» не убедительны: им либо нужно полностью доверять, либо проверять с помощью постоянного тщательного надзора (при условии, что у них даже есть техническое понимание для этого.) Обеспечение измеримых стандартов и объяснение того, как они разумно приближаются к реальным целям, лучше.
  • Для нормализации командного поведения. Заинтересованные стороны, если вы работаете в команде, в которой несколько человек пишут код и тесты, есть место для двусмысленности в отношении того, что считается «хорошо протестированным». У всех ваших коллег одинаковое представление о том, какой уровень тестирования достаточно хорош? Возможно нет. Как вы примиряете это? Найдите метрику, с которой вы все можете согласиться, и примите ее как разумное приближение. Это особенно (но не исключительно) полезно в больших командах, где, например, лидеры могут не иметь прямого контроля над младшими разработчиками. Сети доверия также имеют значение, но без объективных измерений поведение группы может стать непоследовательным, даже если все действуют добросовестно.
  • Чтобы быть честным. Даже если вы являетесь единственным разработчиком и единственным заинтересованным лицом для вашего проекта, вы можете иметь определенные качества программного обеспечения. Вместо постоянной субъективной оценки того, насколько хорошо протестировано программное обеспечение (что требует работы), вы можете использовать покрытие кода в качестве разумного приближения и позволить машинам измерить его для вас.

Какие показатели использовать

Покрытие кода - это не одна метрика; Есть несколько разных способов измерения покрытия. Какой из них вы можете установить стандарт, зависит от того, что вы используете этот стандарт для удовлетворения.

Я буду использовать две общие метрики в качестве примеров того, когда вы можете использовать их для установления стандартов:

  • Охват заявлений : какой процент заявлений был выполнен во время тестирования? Полезно, чтобы получить представление о физическом охвате вашего кода: сколько написанного мною кода я на самом деле протестировал?
    • Этот вид освещения поддерживает более слабый аргумент правильности, но также легче достичь. Если вы просто используете покрытие кода, чтобы гарантировать, что что- то тестируется (а не как показатель качества теста выше этого), то, вероятно, достаточно покрытия заявления.
  • Покрытие ветвлений: когда существует логика ветвления (например, an if), были ли оценены обе ветви? Это дает лучшее представление о логическом охвате вашего кода: сколько возможных путей может пройти мой код, если я проверил?
    • Этот вид охвата является гораздо лучшим показателем того, что программа была протестирована на всестороннем наборе входных данных. Если вы используете покрытие кода как лучшее эмпирическое приближение для уверенности в правильности, вам следует установить стандарты на основе покрытия филиала или аналогичного.

Существует много других метрик (например, покрытие строк аналогично покрытию операторов, но дает разные числовые результаты для многострочных операторов; условное покрытие и покрытие путей аналогично покрытию ветвей, но отражают более подробный вид возможных перестановок выполнение программы вы можете столкнуться.)

Какой процент требовать

Наконец, вернемся к первоначальному вопросу: если вы устанавливаете стандарты покрытия кода, каким должно быть это число?

Надеемся, что на данный момент ясно, что мы говорим о приближении для начала, поэтому любое число, которое мы выберем, будет по своей природе приблизительным.

Некоторые цифры, которые можно выбрать:

  • 100% . Вы можете выбрать это, потому что хотите быть уверенным, что все проверено. Это не дает вам никакого представления о качестве теста, но говорит о том, что какой-то тест качества затронул каждое утверждение (или ветвь и т. Д.). Опять же, это возвращается к степени уверенности: если ваш охват ниже 100% Вы знаете, что часть вашего кода не проверена.
    • Некоторые могут утверждать, что это глупо, и вам следует тестировать только те части кода, которые действительно важны. Я бы сказал, что вам следует поддерживать только те части кода, которые действительно важны. Покрытие кода можно улучшить, удалив также непроверенный код.
  • 99% (или 95%, другие цифры в начале девяностых годов). Подходит для случаев, когда вы хотите передать уровень доверия, близкий к 100%, но оставьте себе некоторый запас, чтобы не беспокоиться о случайном трудном для проверки углу код.
  • 80% . Я видел это число в использовании несколько раз, и не совсем знаю, откуда оно. Я думаю, что это может быть странным незаконным присвоением правила 80-20; Как правило, цель здесь - показать, что большая часть вашего кода протестирована. (Да, 51% также будет «большинством», но 80% больше отражает то, что большинство людей подразумевают под большинством.) Это подходит для случаев среднего уровня, где «хорошо проверенный» не является приоритетным (вы не Я не хочу тратить усилия на тесты с низкой стоимостью), но этого достаточно, чтобы иметь какой-то стандарт.

Я не видел цифры ниже 80% на практике, и мне трудно представить себе случай, когда их можно было бы установить. Роль этих стандартов заключается в повышении уверенности в правильности, и цифры ниже 80% не особенно внушают доверие. (Да, это субъективно, но опять же, идея состоит в том, чтобы сделать субъективный выбор один раз, когда вы устанавливаете стандарт, а затем использовать объективное измерение в будущем.)

Другие заметки

Вышесказанное предполагает, что правильность является целью. Покрытие кода - это просто информация; это может иметь отношение к другим целям. Например, если вас беспокоит возможность сопровождения, вы, вероятно, беспокоитесь о слабой связи, что может быть продемонстрировано тестируемостью, которая, в свою очередь, может быть измерена (в некоторых моделях) по охвату кода. Таким образом, ваш стандарт покрытия кода обеспечивает эмпирическую основу для аппроксимации качества «ремонтопригодности».

killscreen
источник
Хороший ответ. Можете ли вы помочь мне в поиске функциональных возможностей с помощью модульных тестов? Любые инструменты, которые могут помочь мне достичь этого?
Curlyreggie
2
Отличный ответ. Это единственный метод, который фокусируется на тестировании как командной проблеме в промышленных условиях. Я не могу все пересмотреть, и моя команда очень яркая, но зеленая. Я установил процентный уровень 90% для нового проекта в качестве проверки работоспособности для младших разработчиков, а не потому, что я считаю, что этого «достаточно». «90%» и «положительный, отрицательный и нулевой» являются легкими мантрами для ярких, молодых разработчиков, которые, как я знаю, сработают хорошо, но у них нет опыта, чтобы идти вперед и написать дополнительный тестовый пример, который раздражает в глубине души.
0x1mason
2
Я думаю, что это лучший доступный ответ.
bugkiller
27

Мой любимый код покрытия на 100% со звездочкой. Звездочка появляется потому, что я предпочитаю использовать инструменты, которые позволяют помечать определенные строки как строки, которые «не считаются». Если я покрыл 100% строк, которые «считаются», я закончил.

Основной процесс:

  1. Я пишу свои тесты, чтобы реализовать все функциональные возможности и крайние случаи, о которых я могу думать (обычно работая из документации).
  2. Я запускаю инструменты покрытия кода
  3. Я проверяю любые строки или пути, которые не охвачены, и те, которые я считаю не важными или недоступными (из-за защитного программирования), я отмечаю как не считающиеся
  4. Я пишу новые тесты, чтобы покрыть недостающие строки и улучшить документацию, если эти крайние случаи не упомянуты.

Таким образом, если я и мои соавторы добавим новый код или изменим тесты в будущем, есть яркая линия, чтобы сообщить нам, если мы пропустили что-то важное - охват упал ниже 100%. Тем не менее, он также обеспечивает гибкость для решения различных приоритетов тестирования.

Одноименный
источник
3
@ErikE Астерикс, конечно, короткий, но бесстрашный воин из Галлии, который создает исключения для монотонной римской оккупации, и поэтому маленький типографский символ, отмечающий исключения, был назван в его честь. (Более серьезно, спасибо, я исправил опечатку.)
Eponymous
3
Не хотите ли включить «инструменты, которые позволяют [вам] помечать определенные строки как строки, которые не учитываются»?
Домдамброджа
2
@domdambrogia В качестве примера в PHP, если вы используете библиотеку покрытия кода Бергманна, добавьте строку с комментарием, // @codeCoverageIgnoreи она будет исключена из покрытия.
епископ
19

У меня был бы еще один анектод на тестовом освещении, которым я хотел бы поделиться

У нас есть огромный проект, в котором, через твиттер, я заметил, что при 700 модульных тестах мы покрываем только 20% кода .

Скотт Хансельман ответил словами мудрости :

Это право 20%? Это 20%, которые представляют код, который пользователи чаще всего используют? Вы можете добавить еще 50 тестов и добавить только 2%.

Опять же, это восходит к моему Testivus на Code Coverage Answer. Сколько риса вы должны положить в кастрюлю? Это зависит.

Джон Лимджап
источник
Очевидно, здесь должен быть здравый смысл. Не стоит использовать, если 50% кода, который вы тестируете, являются комментариями.
здравомыслие
2
Это больше в линиях ... тратится ли ваше покрытие на основную функциональность вашего приложения, или это бесполезное тестирование тривиальных функций / приятных вещей?
Джон Лимджап
звучит так, как будто большой процент вашего кода - это или шаблон, или обработка исключений, или условный «режим отладки»
Эрик Аронести,
8

Для хорошо спроектированной системы, где модульные тесты привели к развитию с самого начала, я бы сказал, что 85% - это довольно низкое число. Небольшие классы, предназначенные для тестирования, не должны быть трудными для лучшего понимания.

Этот вопрос легко отклонить чем-то вроде:

  • Выделенные строки не соответствуют проверенной логике, и не следует слишком много читать в процентах.

Правда, но есть некоторые важные моменты, которые необходимо сделать в отношении покрытия кода. По моему опыту, эта метрика на самом деле весьма полезна, когда используется правильно. Сказав это, я не видел все системы, и я уверен, что есть тонны их, где трудно увидеть анализ покрытия кода, добавляющий какую-либо реальную ценность. Код может выглядеть по-разному, а объем доступной тестовой среды может варьироваться.

Кроме того, мои рассуждения в основном касаются довольно коротких тестовых петель обратной связи. Для продукта, который я разрабатываю, кратчайший цикл обратной связи является достаточно гибким, охватывающим все, от классовых тестов до межпроцессной сигнализации. Тестирование поставляемого субпродукта обычно занимает 5 минут, и для такого короткого цикла обратной связи действительно возможно использовать результаты теста (и, в частности, метрику покрытия кода, которую мы здесь рассматриваем), чтобы отклонить или принять коммиты в репозитории.

При использовании метрики покрытия кода у вас должен быть не только фиксированный (произвольный) процент, который должен быть выполнен. Это, на мой взгляд, не дает вам реальных преимуществ анализа покрытия кода. Вместо этого определите следующие метрики:

  • Low Water Mark (LWM), наименьшее количество непокрытых линий, когда-либо замеченных в тестируемой системе
  • High Water Mark (HWM), самый высокий процент охвата кода, когда-либо замеченный для тестируемой системы

Новый код может быть добавлен только в том случае, если мы не опускаемся выше LWM и не опускаемся ниже HWM. Другими словами, покрытие кода не может уменьшаться , и новый код должен быть покрыт. Обратите внимание, как я должен говорить, а не должен (объясняется ниже).

Но разве это не значит, что будет невозможно вычистить старый проверенный мусор, который вам больше не нужен? Да, и именно поэтому вы должны быть прагматичными в этих вещах. Есть ситуации, когда правила должны быть нарушены, но для вашей типичной ежедневной интеграции мой опыт показывает, что эти метрики весьма полезны. Они дают следующие два значения.

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

  • Тестовое покрытие для унаследованного кода со временем увеличивается. Добавляя новый код и не имея возможности покрыть его тестовым примером, можно попытаться охватить некоторый устаревший код, чтобы обойти правило LWM. Это иногда необходимое мошенничество, по крайней мере, дает положительный побочный эффект, что со временем охват устаревшего кода будет увеличиваться, что делает на практике строгое соблюдение этих правил довольно прагматичным на практике.

И снова, если цикл обратной связи слишком длинный, может быть совершенно непрактично настраивать что-то подобное в процессе интеграции.

Я также хотел бы упомянуть еще два общих преимущества метрики покрытия кода.

  • Анализ покрытия кода является частью динамического анализа кода (в отличие от статического, т.е. Lint). Проблемы, обнаруженные во время динамического анализа кода (с помощью таких инструментов, как семейство Cleany, http://www-03.ibm.com/software/products/en/rational-purify-family ), такие как чтение неинициализированной памяти (UMR), утечки памяти и т. д. Эти проблемы могут быть обнаружены только в том случае, если код покрыт выполненным тестовым примером . Код, который сложнее всего охватить в тестовом примере, обычно является ненормальным случаем в системе, но если вы хотите, чтобы система отказала изящно (т.е. отслеживание ошибок вместо сбоя), вам может потребоваться приложить некоторые усилия для покрытия ненормальных случаев в динамическом анализе кода, а также. С небольшим количеством неудачи UMR может привести к segfault или хуже.

  • Люди гордятся сохранением 100% нового кода, и люди обсуждают проблемы тестирования с такой же страстью, как и другие проблемы реализации. Как можно написать эту функцию более тестируемым образом? Как бы вы попытались раскрыть этот ненормальный случай и т. Д.

И негатив, для полноты.

  • В большом проекте, в котором участвует много разработчиков, каждый не обязательно станет гением-тестером. Некоторые люди склонны использовать метрику покрытия кода в качестве доказательства того, что код протестирован, и это очень далеко от истины , как упоминалось во многих других ответах на этот вопрос. Это ОДИН показатель, который может дать вам хорошие преимущества при правильном использовании, но если он используется не по назначению, это может привести к плохому тестированию. Помимо очень ценных побочных эффектов, упомянутых выше, покрытая строка только показывает, что тестируемая система может достичь этой линии для некоторых входных данных и что она может выполняться без зависания или сбоя.
Мартин Г
источник
7

Если бы это был идеальный мир, 100% кода было бы охвачено модульными тестами. Однако, поскольку это НЕ идеальный мир, это вопрос того, на что у вас есть время. В результате я рекомендую уделять меньше внимания конкретному проценту и уделять больше внимания критическим областям. Если ваш код написан хорошо (или, по крайней мере, его разумная факсимильная связь), должно быть несколько ключевых моментов, когда API-интерфейсы подвергаются воздействию другого кода.

Сосредоточьте свои усилия на тестировании на этих API. Убедитесь, что API-интерфейсы 1) хорошо документированы и 2) написаны тестовые примеры, соответствующие документации. Если ожидаемые результаты не совпадают с документами, то у вас есть ошибка в вашем коде, документации или тестовых случаях. Все из которых хорошо проверить.

Удачи!

64BitBob
источник
6

Многие магазины не ценят тесты, поэтому, если вы выше нуля, по крайней мере, есть некоторая оценка стоимости - так что, возможно, ненулевое значение не так уж плохо, так как многие все еще равны нулю.

В мире .Net люди часто цитируют 80% как разумные. Но они говорят это на уровне решения. Я предпочитаю измерять на уровне проекта: 30% может подойти для проекта пользовательского интерфейса, если у вас есть Selenium и т. Д. Или ручные тесты, 20% для проекта на уровне данных может подойти, но 95% + вполне достижимо для бизнеса слой правил, если не совсем необходимо. Таким образом, общий охват может быть, скажем, 60%, но критическая бизнес-логика может быть намного выше.

Я также слышал это: стремитесь к 100%, и вы получите 80%; но стремитесь к 80%, и вы попадете на 40%.

Итог: примените правило 80:20, и пусть подсчет ошибок вашего приложения поможет вам.

Грег Тревеллик
источник
5

Покрытие кода - это просто еще один показатель. Само по себе это может вводить в заблуждение (см. Www.thoughtworks.com/insights/blog/are-test-coverage-metrics-overrated ). Поэтому ваша цель должна заключаться не в достижении 100% покрытия кода, а в том, чтобы вы тестировали все соответствующие сценарии своего приложения.

klementtt
источник
4

85% было бы хорошей отправной точкой для проверки критериев.

Я бы, вероятно, выбрал множество более высоких столбцов для критериев доставки - в зависимости от критичности тестируемых подсистем / компонентов.

stephbu
источник
54
Как вы пришли к этому проценту?
здравомыслие
Как примечание - это может быть грязно для проектов, где автоматизация трудна - как всегда, прагматично относиться к тому, что достижимо или желательно.
Стефбу
4
Главным образом через эксперименты. Довольно просто достичь покрытия кода до 80-90% для модульных тестов, связанных с Dev - для повышения обычно требуется вмешательство божественного тестирования - или действительно простые пути кода.
Стефбу
1
Я обычно начинаю с 1) основных путей кода времени выполнения 2) очевидных случаев исключения, которые я явно выбрасываю 3) условных случаев, которые заканчиваются словом «сбой». Это обычно приводит вас к диапазону 70-80. фаззинг и т. д. Рефакторинг, позволяющий вводить методы и т. д. Я обычно выделяю как минимум столько же времени для написания / рефакторинга тестовых разработок, сколько сам основной код.
Стефбу
4

Я использую cobertura, и независимо от процента, я бы рекомендовал обновлять значения в задаче cobertura-check. Как минимум, продолжайте поднимать totalallinerate и totalbranchrate чуть ниже текущего покрытия, но никогда не уменьшайте эти значения. Также свяжите свойство сбоя сборки Ant с этой задачей. Если сборка не удалась из-за отсутствия покрытия, вы знаете, что кто-то добавил код, но не проверял его. Пример:

<cobertura-check linerate="0"
                 branchrate="0"
                 totallinerate="70"
                 totalbranchrate="90"
                 failureproperty="build.failed" />
Гари Кефарт
источник
4

Когда я думаю, что мой код недостаточно тестирован, и я не уверен, что тестировать дальше, я использую покрытие, чтобы решить, что тестировать дальше.

Если я увеличу покрытие в модульном тесте - я знаю, что этот модульный тест чего-то стоит.

Это касается кода, который не покрывается, покрывается на 50% или на 97%.

Брикнер
источник
3
Я полностью не согласен. Модульный тест чего-то стоит, только если есть вероятность, что он обнаружит ошибку (либо ошибку, существующую сейчас, либо ошибку регрессии в будущем); или если это помогает документировать поведение вашего класса. Если метод настолько прост, что он не может действительно потерпеть неудачу, такой как однострочный метод получения, тогда для обеспечения модульного теста для него есть нулевое значение.
Дауд ибн Карим
6
У меня были ошибки в одной строке геттеров. Исходя из моего опыта, нет кода без ошибок. Там нет метода, который не может действительно потерпеть неудачу.
brickner
1
Предполагая, что ваш однострочный геттер используется другим кодом, который вы выполняете, и тесты этого кода проходят, вы также косвенно охватили однострочный геттер. Если вы не используете геттер, что он делает в вашем коде? Я согласен с Дэвидом Уоллесом… нет необходимости напрямую тестировать простые вспомогательные функции, которые используются в других местах, если код и тесты, зависящие от помощника, не показывают, что с ним могут быть проблемы.
Лоуэлл Монтгомери
@LowellMontgomery, а что, если тест для вашего другого кода не пройден из-за однострочного геттера (который не тестировался)? Если бы был тест для однострочника, было бы намного легче найти причину сбоя. Это становится действительно плохо, когда сотни не протестированных однострочников используются в нескольких разных местах.
Даниил
Предполагалось, что тесты с использованием однострочного пройденного геттера. Если это не удалось (например, когда вы пытаетесь использовать возвращаемое значение вашего однострочного геттера), то вы можете разобраться с этим. Но если нет действительно насущной причины быть таким параноиком, вы должны провести черту где-нибудь. Мой опыт показывает, что мне нужно расставлять приоритеты в том, что отнимает у меня время и внимание, и действительно простым «добытчикам» (этой работе) не нужны отдельные тесты. Это время может быть потрачено на то, чтобы сделать другие тесты лучше или обеспечить более полное покрытие кода, который с большей вероятностью не сработает. (т.е. я стою на своей первоначальной позиции с Дэвидом Уоллесом).
Лоуэлл Монтгомери
4

Я предпочитаю делать BDD, который использует комбинацию автоматических приемочных тестов, возможно, других интеграционных тестов и модульных тестов. Вопрос для меня заключается в том, каким должно быть целевое покрытие автоматизированного набора тестов в целом.

Кроме того, ответ зависит от вашей методологии, языка и инструментов тестирования и охвата. При выполнении TDD в Ruby или Python не сложно поддерживать 100% покрытие, и это того стоит. Намного проще управлять 100% -ным покрытием, чем 90-процентным покрытием. То есть, гораздо легче заполнить пробелы в покрытии по мере их появления (и когда хорошо работают пробелы в TDD, они редки и обычно стоят вашего времени), чем управлять списком пробелов в охвате, с которыми вы еще не сталкивались, и пропускать покрытие регрессия из-за вашего постоянного фона непокрытого кода.

Ответ также зависит от истории вашего проекта. Я обнаружил, что все вышеперечисленное практично в проектах, управляемых таким образом с самого начала. Я значительно улучшил охват крупных унаследованных проектов, и это того стоило, но я никогда не считал целесообразным возвращаться назад и заполнять все пробелы в охвате, потому что старый непроверенный код недостаточно хорошо понят, чтобы делать это правильно и быстро.

Дейв Швейсгут
источник
3

Если вы проводили модульное тестирование в течение приличного количества времени, я не вижу причин, чтобы оно не приближалось к 95% +. Однако, как минимум, я всегда работал с 80%, даже когда плохо знаком с тестированием.

Это число должно включать только код, написанный в проекте (исключая фреймворки, плагины и т. Д.), И, возможно, даже исключать определенные классы, состоящие полностью из кода, написанного из обращений к внешнему коду. Этот вид вызова должен быть посмешищем / заглушен.

Тони Питале
источник
3

Вообще говоря, из нескольких статей о передовых практиках в области инженерного совершенства, которые я прочитал, 80% для нового кода в модульных тестах - это точка, которая дает наилучшую отдачу. Более того, CC% приводит к меньшему количеству дефектов по сравнению с приложенным усилием. Это лучшая практика, которая используется многими крупными корпорациями.

К сожалению, большинство из этих результатов являются внутренними для компаний, поэтому я не могу указать вам ни одной публичной литературы.

user17222
источник
3

Покрытие кода - это здорово, но только до тех пор, пока выгоды от него перевешивают затраты / усилия по его достижению.

Некоторое время мы работали на уровне 80%, однако мы только что приняли решение отказаться от этого и вместо этого сосредоточиться на тестировании. Концентрируясь на сложной бизнес-логике и т. Д.,

Это решение было принято из-за растущего количества времени, которое мы тратили на отслеживание кода и поддержку существующих модульных тестов. Мы почувствовали, что дошли до того, что польза, которую мы получили от покрытия кода, оказалась меньше усилий, которые мы должны были приложить для его достижения.

Саймон Креп
источник
2

Краткий ответ: 60-80%

Длинный ответ: я думаю, что это полностью зависит от характера вашего проекта. Обычно я начинаю проект с модульного тестирования каждого практического элемента. К первому «релизу» проекта у вас должен быть довольно хороший базовый процент в зависимости от типа программирования, которым вы занимаетесь. С этого момента вы можете начать «обеспечивать» минимальное покрытие кода.

user11087
источник
2

Проверьте Crap4j . Это немного более сложный подход, чем прямое покрытие кода. Он объединяет измерения покрытия кода с измерениями сложности, а затем показывает, какой сложный код в настоящее время не тестируется.

Дон Киркби
источник
2

Мой ответ на эту загадку состоит в том, чтобы охватить 100% строк кода, который вы можете протестировать, и 0% покрытия строк кода, который вы не можете протестировать.

Моя текущая практика в Python - делить мои модули .py на две папки: app1 / и app2 / и при запуске модульных тестов вычислять покрытие этих двух папок и визуально проверять (я должен когда-нибудь автоматизировать это), что app1 имеет 100% покрытие и Приложение 2 имеет покрытие 0%.

Когда / если я нахожу, что эти цифры отличаются от стандарта, я исследую и изменяю дизайн кода, чтобы охват соответствовал стандарту.

Это значит, что я могу рекомендовать достичь 100% покрытия строк кода библиотеки.

Я также иногда просматриваю app2 /, чтобы посмотреть, смогу ли я там протестировать какой-либо код, и если я могу, переместить его в app1 /

Теперь я не слишком беспокоюсь о совокупном охвате, потому что он может сильно варьироваться в зависимости от размера проекта, но в целом я видел от 70% до более 90%.

С помощью Python я смог бы разработать тест на дым, который мог бы автоматически запускать мое приложение при измерении покрытия и, надеюсь, получить совокупный показатель 100% при сочетании теста на дым с показателями единичного теста.

quamrana
источник
2

Просмотр покрытия с другой точки зрения: Хорошо написанный код с четким контролем является наиболее простым для охвата, самым легким для чтения и обычно наименее ошибочным кодом. Написав код с учетом ясности и совместимости, а также написав модульные тесты параллельно с кодом, вы получите наилучшие результаты, IMHO.


источник
2

На мой взгляд, ответ: «Это зависит от того, сколько у вас времени». Я пытаюсь достичь 100%, но я не суетюсь, если не получаю со временем.

Когда я пишу модульные тесты, я ношу шляпу, отличную от шляпы, которую я использую при разработке производственного кода. Я думаю о том, на что претендует протестированный код и какие ситуации могут его сломать.

Я обычно следую следующим критериям или правилам:

  1. Что модульный тест должен быть формой документации о том, что ожидаемое поведение моих кодов, т.е. ожидаемый результат при определенном входном сигнале и исключения, которые могут выдавать клиенты, которые могут захотеть поймать (Что должны знать пользователи моего кода?)

  2. Что модульный тест должен помочь мне выяснить, что, если условия, о которых я, возможно, еще не думал. (Как сделать мой код стабильным и надежным?)

Если эти два правила не дают 100% покрытия, пусть будет так. Но однажды у меня есть время, я анализирую непокрытые блоки и строки и определяю, есть ли еще тестовые случаи без юнит-тестов или нужно реорганизовать код для устранения ненужных кодов.

Марк Менчавез
источник
1

Это сильно зависит от вашего приложения. Например, некоторые приложения состоят в основном из кода GUI, который нельзя тестировать модулем.

Томас
источник
5
Вам, вероятно, следует использовать Model View Presenter для своего пользовательского интерфейса, если вы находитесь в среде TDD.
Чарльз Грэм
1

Я не думаю, что может быть такое черно-белое правило.
Кодекс должен быть пересмотрен, с особым вниманием к критическим деталям.
Однако, если это не было проверено, у него есть ошибка!

Nescio
источник
Не хотите правила, просто отзывы о личном опыте о корреляции между процентом покрытия кода и эффективностью модульного теста.
здравомыслие
1

В зависимости от критичности кода, от 75% до 85% - хорошее правило. Код доставки обязательно должен быть проверен более тщательно, чем в коммунальных службах и т. Д.

Уильям Келлер
источник
1

Это должно зависеть от того, на какой стадии жизненного цикла разработки вашего приложения вы находитесь.

Если вы уже некоторое время разрабатываете и уже внедрили много кода и только сейчас понимаете, что вам нужно подумать о покрытии кода, то вам нужно проверить текущее покрытие (если оно существует), а затем использовать этот базовый уровень для устанавливать вехи на каждый спринт (или средний рост за период спринтов), что означает принятие долга кода при продолжении приносить пользу конечному пользователю (по крайней мере, по моему опыту, конечному пользователю все равно, если вы увеличили тест) покрытие, если они не видят новые функции).

В зависимости от вашего домена, стрелять по 95% не является необоснованным, но я бы сказал, что в среднем вы будете рассматривать средний случай от 85% до 90%.

codeLes
источник
1

Я думаю, что лучшим признаком правильного покрытия кода является то, что количество конкретных проблем, которые помогают устранить модульные тесты, разумно соответствует размеру созданного вами кода модульных тестов.

dimarzionist
источник
1

Я думаю, что самое важное - это знать, какова тенденция покрытия с течением времени, и понимать причины изменений в тренде. Считаете ли вы изменения в тренде хорошими или плохими, зависит от вашего анализа причины.

Роб Скотт
источник
0

Мы нацеливались на> 80% до нескольких дней назад, но после того, как мы использовали много сгенерированного кода, мы не заботимся о% age, а скорее заставим рецензента позвонить по поводу требуемого покрытия.

Рева
источник
0

Я думаю, что после публикации в «Фестивале» контекст ответа должен быть вторым программистом. Сказав это с практической точки зрения, нам нужны параметры / цели, к которым нужно стремиться. Я считаю, что это можно «проверить» в Agile-процессе, проанализировав код, у нас есть архитектура, функциональность (пользовательские истории), а затем придумать число. Исходя из моего опыта работы в сфере телекоммуникаций, я бы сказал, что 60% - это хорошее значение для проверки.

D Lovece
источник