2009-03-30 4 views
30

Я ищу примеры реального мира некоторых побочных эффектов покрытия кода.Ловушки покрытия кода

Я заметил, что это произошло недавно на работе из-за политики, обеспечивающей покрытие 100% кода. Качество кода улучшилось точно, но, напротив, тестеры, похоже, пишут более лёгкие планы тестирования, потому что «ну код полностью протестирован». В результате некоторые логические ошибки удалось ускользнуть. Они были ДЕЙСТВИТЕЛЬНО БОЛЬНЫМ, чтобы отлаживать, потому что «ну, код полностью протестирован».

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

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

Заранее спасибо.

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

+0

ask jeff - я не думаю, что у него есть эта проблема. Я думаю, что stackoverflow имел 5% -ный охват кода в последний раз, когда я услышал цифру :-) –

+0

Ха-ха, я думаю, что разница в том, что Джефф, вероятно, кодирует намного лучше меня и людей, которых я знаю =) – Fung

+0

Нет никакой славы в тестировании, строит , или устанавливает. Вы только заметили, когда дела идут в дерьмо, и если вы делаете свою работу правильно нада. Хороший вопрос ... – ojblass

ответ

52

В предложении: Покрытие кода говорит вам, что вы определенно не испытаны, не то, что вы есть.

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

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

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

Кроме того, люди начинают одержимы/возиться с цифрами, а не фокусироваться на качестве тестов. Я видел плохо написанные тесты, у которых есть 90 +% покрытия, так же, как я видел отличные тесты, которые имеют только 60-70% охвата.

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

+2

+1 Очень хорошее объяснение «проблемы» с охватом кода. –

+1

+1 Мне всегда нравится, когда я проголосую за другого, даже когда у меня есть собственный ответ. :-) –

+0

+1. По моему опыту охват кода 40% -70% - это магическое число. Ниже у вас недостаточно защиты от ретроспективных ошибок. Выше того, что вы в конечном итоге пишете бессмысленные тесты, такие как тестирование геттеров и сеттеров, которые мешают, а не помогают развитию. Слишком высокий охват кода делает его медленнее и сложнее в рефакторе. Вам нужно всего лишь достаточно, чтобы укусить вас, когда вы делаете что-то не так, не слишком сильно, чтобы вы не были спонтанными. Также рассмотрите тесты без ценности.Если тест постоянно ломается, но на самом деле это не доказывает, удалите его! Или .. найти лучший способ выразить тест –

5

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

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

Было бы много работы впустую.

+0

Я действительно когда-то видел проблему на dev-машине, которая возникла из UnsupportedEncodingException для UTF-8. Это тоже должно быть встроено, но на этой машине была установлена ​​бета-версия JDK Sun, где она не была ... –

+1

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

2
  1. Написание слишком целенаправленных тестовых примеров.
  2. Недостаточное тестирование изменчивости ввода кода
  3. Выполнено большое количество искусственных тестовых случаев.
  4. Не концентрируясь на важных ошибках испытаний из-за шума.
  5. Сложность в назначении дефектов, потому что многие условия из многих компонентов должны взаимодействовать для выполняемой строки.

Худший побочный эффект от цели покрытия 100% состоит в том, чтобы потратить много циклов разработки тестов (75% +) на угловые случаи. Другим слабым эффектом такой политики является концентрация удара по конкретной линии кода, а не обращение к диапазону входных данных. Мне все равно, что функция strcpy запускалась хотя бы один раз. Мне действительно все равно, что он работал с большим количеством входных данных. Хорошая политика. Но любая драконовская политика плоха. 100% -ный показатель охвата кода не является ни необходимым, ни достаточным для того, чтобы код считался сплошным.

16

Просто потому, что покрытие кода не означает, что вы на самом деле проверяете все пути через функцию.

Например, этот код имеет четыре пути:

if (A) { ... } else { ... } 
if (B) { ... } else { ... } 

Однако только в двух тестах (например, один с А и В истинной, одна с А и В ложной) будет давать «покрытие кода 100%.»

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

1

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

18

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

for (int i = 0; i < MAX_RETRIES; ++i) { 
    if (someFunction() == MAGIC_NUMBER) { 
     break; 
    } 
} 

... никогда не тестирует условие завершения на цикл.

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

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

1

! 00% код покрытия означает хорошо проверенный код - это полный миф. В качестве разработчиков мы знаем жесткие/сложные/деликатные части системы, и я бы предпочел бы увидеть те области, которые были правильно протестированы, и получить только 50% -ный охват, а не бессмысленную цифру, что каждая строка была запущена хотя бы один раз.

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

3

Я знаю, что это не является прямым ответом на ваш вопрос, но ...

Любое тестирование, независимо от того, какого типа, недостаточно само по себе. Модульное тестирование/покрытие кода для разработчиков. QA все еще нуждается в тестировании системы в целом. Бизнес-пользователям по-прежнему необходимо тестировать систему в целом.

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

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

1

У нас есть хорошие инструменты для измерения покрытия кода от модульных испытаний. Поэтому соблазнительно полагаться на покрытие кода на 100%, чтобы представить, что вы «прошли тестирование». Это неправда.

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

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

Я также писал о этом недавно: http://karwin.blogspot.com/2009/02/unit-test-coverage.html

5

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

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

1

100% покрытия кода не означает, что вы сделали с usnit тесты

function int divide(int a, int b) { 
    return a/b; 
} 

С помощью всего лишь 1 единицу теста, я получаю покрытие кода 100% для этой функции:

return divide(4,2) == 2; 

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

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

2

Одна из самых больших подводных камней покрытия кода заключается в том, что люди просто говорят о покрытии кода, фактически не указав , что тип покрытия кода, о котором они говорят. Характеристики C0, C1, C2 и даже более высокие уровни охвата кода составляют очень, поэтому просто говорить о «охвате кода» даже не имеет смысла.

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

OTOH, достижение 100% покрытия C0 тривиально.

Еще одна важная вещь, которую следует помнить, заключается в том, что покрытие кода не сообщает вам, какой код был протестирован. Он сообщает только, какой код был run! Вы можете попробовать сами: взять кодовую базу с 100% охватом кода. Удалите все утверждения из тестов. Теперь код все еще имеет покрытие 100%, но не проверяет ни одной вещи! Таким образом, покрытие кода не сообщает вам, что тестировалось, только то, что не тестировалось.

2

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

непосредственно с их сайта:

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

+0

Шут является еще одним аналогичным «тестером». http://jester.sourceforge.net/ –

+0

Шут не очень полезен ни для чего, кроме крошечных игрушечных проектов. Jumble - это улучшение, но в наши дни есть намного лучшие варианты - http://pitest.org/java_mutation_testing_systems/ – henry

Смежные вопросы