Подтвердить что ты не робот

Ловушки покрытия кода

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

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

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

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

Спасибо заранее.

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

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

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

... без проверки условия завершения цикла for.

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

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

Ответ 3

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

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

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

Однако только два теста (например, один с A и B true, один с A и B false) даст "100% -ный охват кода".

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

Ответ 4

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

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

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

Ответ 5

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

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

Ответ 6

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

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

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

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

Ответ 7

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

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

Ответ 8

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

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

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

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

Ответ 9

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

Непосредственно со своего веб-сайта:

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

Ответ 10

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

Ответ 11

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

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

Ответ 12

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

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

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

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

Ответ 13

100% охват кода не означает, что вы закончили с помощью тестов usnit

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

Всего за 1 unit test я получаю 100% -ный охват кода для этой функции:

return divide(4,2) == 2;

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

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