Покрытие кода тестами — Python: Автоматическое тестирование
С ростом проекта становится сложно определить, какой код уже протестирован, а какой — еще нет. При этом подобная потребность возникает регулярно. Обычно это происходит тогда, когда не все члены команды ответственно подходят к написанию тестов. В таком случае может страдать качество проекта.
Но есть решение — протестированность кода можно измерить. В этом уроке мы познакомимся с метрикой, которая помогает подсчитать количество тестов и качество тестирования.
Как работает покрытие тестами
В тестировании часто используют метрику code coverage — это покрытие кода тестами. Покрытие анализируется тестовыми фреймворками, которые считают отношения строчек, задействованных в тестах, ко всем строчкам исходного кода.
Например, если в коде есть условная конструкция, не проверенная тестами, то все строки кода в этой конструкции будут не покрытыми.
В Pytest покрытие измеряется крайне просто. Достаточно установить одну зависимость и запустить тесты с правильным флагом:
--cov # Примерный вывод tests/test_example.py .. [ 66%] tests/test_hexlet_pytest.py . [100%] Name Stmts Miss Cover ----------------------------------------------- hexlet_pytest/__init__.py 1 0 100% hexlet_pytest/example.py 4 1 75% ----------------------------------------------- TOTAL 5 1 80%
После всех тестов Pytest выводит сводную таблицу по каждому файлу. В ней показан процент покрытия кода тестами.
В примере выше видно, что в файле _init_.py покрыто 100% кода, а вот в файле example.py — только 75%. При этом общее покрытие кода 80%.
Обратите внимание, что покрытие сильно зависит от того, какие тесты выполнились. Если часть тестов упало с ошибкой, то Pytest покажет намного меньшее покрытие — тесты просто не доберутся до всего кода. Поэтому покрытие измеряют только тогда, когда все тесты зеленые.
Эта статистика помогает найти места, где тестов мало. Дальше по ситуации их можно добавлять. Если в проекте тестов не было вообще, то эта статистика начинает быстро расти. А вот дальше, ближе к 90 процентам, придется бороться за каждую строчку кода.
Каким должно быть покрытие
Само по себе покрытие не гарантирует, что код работает правильно во всех ситуациях. Логические ошибки в коде невозможно отследить только покрытием. Для этого нужны тесты на одну и ту же функциональность, но с разным набором данных.
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Как использовать Coverage в Django
Когда вы разрабатываете большой проект, случайно можно забыть некоторые части кода, которые нужно протестировать. Coverage.py — это инструмент на python, который поможет вам в этом.
Установка
Используйте pip или easy_install, как вам по душе
pip install coverageЗапуск и удаление
Для запуска в проекте Django используйте команду:
overage run --source='.' manage.py test the-app-you-want-to-testЭта команда заполнит «.coverage», который расположен в COVERAGE_FILE, а затем вы можете увидеть результаты или отчет. Если вам нужно удалить полученные данные, воспользуйтесь командой:
coverage eraseДля одного файла
Если вы хотите проверить только код Python, то вам необходимо сделать:
coverage run your_program.py arg1 arg2 arg3Есть несколько дополнительных опций, которые вы можете посмотреть по ссылке .
О шаблонах можно узнать в разделе плагинов .Просмотр результата
Если вы хотите вывести результаты в командной строке:
coverage reportДля более понятных и удобных отчетов:
coverage htmlЧтобы точно знать, какая часть вашего кода покрыта тестами, используйте следующую команду:
coverage annotate -d directory-where-to-put-annotated-filesПрограмма сгенерирует тот же файл исходного кода с дополнительным синтаксисом:
- Строка с «>» означает, что она была выполнена.
- Строка, начинающаяся с «!», Означает, что она не была выполнена.
- Строка, начинающаяся с «-» означает, что строка была исключена из статистики покрытия.
Хороший уровень покрытия
Хорошее покрытие обычно приходится на 90%. Однако, если результат 100%, это может быть плохим сигналом, так как, возможно, дело с покрытием, а не с качеством тестов. Несколько советов:
- Будьте осторожны с качеством ваших тестов.
- Не замедляйте скорости своего разработчика ради покрытия.
- Используйте покрытие, чтобы найти непроверенный код и решить, заслуживает ли он покрытия.
Исключаем код
Иногда нам нужно исключить некоторый код, который не нуждается в покрытии. Существует несколько вариантов:
- Указание файлов для исключения и пропуска в .coveragerc.
- Написание в одной строке блока комментария.
# pragma: no coverНапример, если вы хотите исключить сгенерированный код из покрытия, потому что он должен поддерживаться инструментом генерации:
def generated_code(): # pragma: no cover do_something()
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
По статье задано0 вопрос(ов)
Подписка на обсуждение 2
Подписка на раздел 176Вам это нравится? Поделитесь в социальных сетях!
Как узнать процент покрытия кода тестами?
Использую для тестов unittest. Запускаю через pytest. Каким способом можно узнать процент покрытия кода тестами? Вроде как-то coverage.py можно использовать?
Отслеживать
13k 10 10 золотых знаков 41 41 серебряный знак 78 78 бронзовых знаков
задан 30 ноя 2019 в 14:55
744 6 6 серебряных знаков 19 19 бронзовых знаковЛибо pip install coverage и coverage run pytest && coverage report -m , либо pytest-cov , как в ответе.
30 ноя 2019 в 21:44
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Нужно установить плагин pytest-cov для pytest ( pip install pytest-cov ), при запуске pytest добавить ключ --cov=proj (где proj - имя директории, для файлов которой будет считаться покрытие).
После выполнения тестов создастся файл .coverage с информацией по покрытию. Также можно генерировать отчеты по покрытию, например, в виде html и других форматах (см. pytest-cov - Reporting)
Отслеживать
ответ дан 30 ноя 2019 в 15:11
48.6k 17 17 золотых знаков 56 56 серебряных знаков 100 100 бронзовых знаков
- python
- юнит-тесты
- pytest
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.8.3130
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Что такое покрытие кода?

Покрытие кода представляет собой показатель того, какая часть исходного кода охвачена тестами. Это полезный показатель позволяет оценить качество комплекта тестов. В этой статье мы покажем, как начать работать с ним в собственных проектах.
Как рассчитывается показатель покрытия кода
Чтобы определить, насколько хорошо был испытан код во время выполнения комплекта тестов, инструменты покрытия кода будут использовать один или несколько критериев. К числу типичных показателей, которые можно встретить в отчетах о покрытии, относятся следующие.
- Покрытие функций: сколько объявленных функций было вызвано.
- Покрытие операторов: какая доля содержащихся в программе операторов была выполнена.
- Покрытие веток: сколько выполнено веток контрольной структуры (например, операторов 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() внизу.

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

Покрытие кода: 6 советов для начала работы
1. Найдите подходящий инструмент для своего проекта
В зависимости от используемого языка (или языков) можно найти несколько вариантов создания отчетов о покрытии. Ниже перечислены некоторые из популярных инструментов.
- Java: Atlassian Clover, Cobertura, JaCoCo
- Javascript: istanbul
- PHP: PHPUnit
- Python: Coverage.py
- Ruby: SimpleCov
Сравнение инструментов также поможет вам принять решение. Одни инструменты, такие как istanbul, выводят результаты прямо в терминал, а другие — могут генерировать полный HTML-отчет, из которого можно понять, какая часть кода не покрыта.
2. К какому проценту покрытия следует стремиться?
Покрытие кода — не панацея: высокий процент покрытия не дает гарантии решения всех проблем, если при этом не тестируются критически важные части приложения или если существующие тесты недостаточно надежны, чтобы заранее отлавливать все ошибки. Поэтому считается, что следует стремиться к покрытию кода на уровне 80 %. Попытки достичь более высокого уровня покрытия могут обойтись слишком дорого, но при этом не принести соответствующей выгоды.
Возможно, при первом запуске инструмента покрытия вы обнаружите, что у вас достаточно низкий процент покрытия. Если вы только начинаете внедрять тестирование, это нормальная ситуация. Не стоит мучить себя, пытаясь сразу достичь покрытия в 80 %. Это соображение заключается в том, что поспешное стремление достичь целевого показателя покрытия может подтолкнуть вашу команду к написанию тестов, которые затрагивают как можно больше строк кода, вместо тестов, основанных на бизнес-требованиях приложения.
Например, в приведенном выше примере мы достигли покрытия в 100 %, выполнив тестирование того, являются ли числа 100 и 34 кратными 10. Но что если мы вызовем нашу функцию, передав ей букву вместо числа? Должны ли мы получить истинный или ложный результат? Или мы должны получить исключение? Важно дать команде время подумать о тестировании с точки зрения пользователя, чтобы тесты не выполнялись лишь путем просмотра строк кода. Покрытие кода не укажет вам на то, что вы что-то пропустили в исходном коде.
3. Сначала сфокусируйтесь на модульном тестировании
Назначение модульных тестов состоит в том, чтобы гарантировать работоспособность отдельных методов классов и компонентов, используемых приложением. Они, как правило, не затратны в смысле реализации, быстро выполняются и дают вам полную уверенность в том, что основа платформы надежна. Простой способ быстро увеличить покрытие кода — начать с добавления модульных тестов, поскольку они по определению должны помочь комплекту тестов достигать всех строк кода.
4. Используйте отчеты о покрытии для выявления критических ошибок тестирования
Скоро в вашем коде будет так много тестов, что вы перестанете понимать, какая часть приложения проверяется во время выполнения комплекта тестов. Вы узнаете, что сломалось, когда получите сборку с ошибкой, но вам будет сложно понять, какие компоненты успешно прошли тестирование.
Здесь отчеты о покрытии могут служить источником направляющих указаний для вашей команды. Большинство инструментов позволяет глубоко анализировать отчеты о покрытии для поиска конкретных элементов, которые не были охвачены тестами, а затем использовать результаты этого анализа для определения критически важных частей приложения, которые еще предстоит протестировать.

5. Когда будете готовы, сделайте покрытие кода частью процесса непрерывной интеграции
Если вы не добьетесь достаточно высокого процента покрытия, после запуска рабочего процесса непрерывной интеграции (CI) могут начаться отказы при прохождении тестов. Конечно, как уже сказано выше, было бы неразумно устанавливать слишком высокий порог отказа, а 90-процентное покрытие с высокой вероятностью будет причиной частых отказов сборки. Если ваша цель — 80-процентное покрытие, в качестве подстраховки рассмотрите возможность установить порог отказа на уровне 70 % для сохранения культуры CI.
Повторюсь: избегайте неправильного толкования этой цели, так как давление на команду ради обеспечения высокого уровня покрытия может привести к плохой реализации тестов.
6. Хорошее покрытие — это необязательно хорошие тесты
Чтобы прийти к развитой культуре тестирования, необходимо сперва добиться, чтобы команда понимала, как приложение должно себя вести, когда кто-то использует его правильно и когда кто-то пытается нарушить его работу. Инструменты покрытия кода могут помочь понять, на чем следует сосредоточить внимание в дальнейшем, но они не покажут, достаточно ли надежны существующие тесты с точки зрения проверки непредвиденного поведения.
Достижение высокого уровня покрытия — отличная цель, но она должна сочетаться с наличием надежного комплекта тестов, который может не только гарантировать, что не нарушены отдельные классы, но и проверить целостность системы.
Здесь вы можете узнать больше о различных типах тестирования программного обеспечения. Решение Open DevOps от Atlassian представляет собой платформу с открытым пакетом инструментов, где вы можете создать конвейер разработки с непрерывной поставкой с помощью любимых инструментов. Узнайте из наших руководств по тестированию DevOps, как инструменты Atlassian и сторонних производителей могут интегрировать тестирование в ваш рабочий процесс.

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