Close

Введение в покрытие кода

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

Фотография Стена Питтета
Стен Питтет

Приглашенный автор


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

Как рассчитывается показатель покрытия кода?


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

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

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

Эти показатели взаимосвязаны, но различимы. В приведенном ниже простейшем скрипте у нас есть функция JavaScript, проверяющая, является ли аргумент кратным числу 10. Ниже мы воспользуемся этой функцией, чтобы проверить, кратно ли число 100 числу 10. Это поможет понять разницу между покрытием функций и покрытием веток.

См. решение

Разработка и эксплуатация программного обеспечения с помощью Open DevOps

Связанные материалы

Автоматическое тестирование для DevOps

coverage-tutorial.js

function isMultipleOf10(x) {   if (x % 10 == 0)     return true;   else    return false; }   console.log(isMultipleOf10(100));


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

Получение отчета о покрытии в командной строке

Это потому, что при выполнении нашего скрипта оператор else не был выполнен. Если бы мы хотели получить покрытие в 100 %, можно было бы просто добавить еще одну строку (по сути, еще один тест), чтобы обеспечить использование всех веток с этим оператором.

coverage-tutorial.js

function isMultipleOf10(x) {   if (x % 10 == 0)     return true;   else     return false; }   console.log(isMultipleOf10(100)); console.log(isMultipleOf10(34)); // This will make our code execute the "return false;" statement.  


Второй запуск нашего инструмента покрытия покажет, что покрыто 100 % исходного кода, благодаря наличию двух операторов console.log() внизу.

Достижение стопроцентного покрытия по всем критериям

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

istanbul для Javascript может предоставить подробный отчет о покрытии для каждого пути

Начало работы с покрытием кода


Найдите подходящий инструмент для своего проекта

В зависимости от используемого языка (или языков) можно найти несколько вариантов создания отчетов о покрытии. Ниже перечислены некоторые из популярных инструментов.

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

К какому проценту покрытия следует стремиться?

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

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

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

Сначала сфокусируйтесь на модульном тестировании

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

Используйте отчеты о покрытии для выявления критических ошибок тестирования

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

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

SimpleCov для Ruby может показать, какие методы не были протестированы

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

Если вы не добьетесь достаточно высокого процента покрытия, после запуска процесса непрерывной интеграции (CI) могут начаться отказы при прохождении тестов. Конечно, как уже сказано выше, было бы неразумно устанавливать слишком высокий порог отказа, а 90-процентное покрытие с высокой вероятностью будет причиной частых отказов сборки. Если ваша цель — 80-процентное покрытие, в качестве подстраховки рассмотрите возможность установить порог отказа на уровне 70 % для сохранения культуры CI.

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

Хорошее покрытие — это необязательно хорошие тесты

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

Достижение высокого уровня покрытия — отличная цель, но она должна сочетаться с наличием надежного комплекта тестов, который может не только гарантировать, что не нарушены отдельные классы, но и проверить целостность системы.

Подробнее см. в статье Различные виды тестирования ПО.

Sten Pittet
Sten Pittet

Я уже 10 лет работаю в сфере ПО, занимал различные должности: от разработчика до менеджера продукта. Проработав 5 лет в Atlassian, где я участвовал в создании инструментов разработки, теперь я пишу статьи о разработке ПО. За пределами офиса я работаю над тем, чтобы стать хорошим отцом для своего потрясающего малыша.


Поделитесь этой статьей

Рекомендуемые статьи

Добавьте эти ресурсы в закладки, чтобы изучить типы команд DevOps или получать регулярные обновления по DevOps в Atlassian.

Рисунок: DevOps

Сообщество DevOps

Рисунок: DevOps

Узнать больше в блоге

Рисунок: карта

Начните работу бесплатно

Подпишитесь на информационную рассылку по DevOps

Thank you for signing up

продолжение темы
Microservices and Microservices Architecture