Какое покрытие тестами было в проекте
Что проверяют
Вопрос звучит как про цифру, но проверяют отношение к тестам. Интервьюеру интересно, знаете ли вы реальное число, чем его мерили и что за ним стоит. Следом обычно спрашивают, что покрыто, что не покрыто сознательно и падает ли сборка при просадке.
Как отвечать
Назовите число и сразу разверните его. Голая цифра без разреза не значит ничего.
- чем мерили:
coverage.py, в связке с pytest этоpytest --cov=app --cov-report=term-missing. Обязательно скажите про--cov-branch: строчное покрытие завышает картину, а покрытие ветвлений показывает непройденныеelseи ранние выходы; - как распределено: «85 процентов по проекту» это средняя температура. Полезнее сказать так: доменная логика и расчёты около 95, тонкие обёртки над клиентами и админка почти не покрыты, и это осознанное решение;
- что исключено: миграции, сгенерированный код, блоки
if TYPE_CHECKING, точки входа. Всё это лежит вexclude_linesсекции[tool.coverage]вpyproject.toml; - где стоит порог:
--cov-fail-underв CI плюс проверка покрытия только изменённых строк на пул-реквесте. Это честнее общего процента: новый код обязан быть покрыт, а старый подтягивается по мере правок; - пирамида: сколько юнит-тестов, сколько интеграционных с настоящей базой через
testcontainersили временную схему, есть ли контрактные. Время полного прогона тоже часть ответа.
Сильный ход это рассказать, где покрытие обмануло. Тест, который вызывает функцию и не проверяет результат, даёт зелёный процент и нулевую пользу. Если пробовали мутационное тестирование (mutmut), скажите, сколько мутантов выжило при девяноста процентах покрытия. Числа называйте свои.
Где спотыкаются
Называют круглую цифру без источника. «Процентов восемьдесят» без инструмента и без разреза по модулям читается как догадка.
Защищают сто процентов как цель. Погоня за последними процентами рождает тесты на геттеры и на __repr__, а баги живут в интеграциях, куда покрытие вообще не смотрит.
Отвечают «тестов не было» и замолкают. Гораздо лучше продолжить: с чего начали бы, какой модуль ломается чаще всего, почему первым шагом идёт регрессионный тест на пойманный баг.