Тестирование
Модульные тесты, pytest, моки и инструменты проверки кодстайла.
6 вопросов
JuniorТеорияОчень частоЧто такое мокирование в тестах?
Что такое мокирование в тестах?
Замена реальной зависимости (сеть, диск, БД, внешний сервис) поддельной заглушкой, которая имитирует её интерфейс, чтобы тест оставался изолированным, быстрым и детерминированным. В Python это даёт unittest.mock (Mock/patch).
Типичные ошибки
- ✗Проверять поведение самого мока, а не тестируемого кода
- ✗Патчить неверный путь импорта, из-за чего реальная зависимость всё равно работает
Уточняющие вопросы
- →В чём разница между mock, stub и fake?
- →Почему
patchнужно применять там, где имя ищется, а не где определено?
JuniorТеорияЧастоКакие инструменты проверяют стиль и качество Python-кода?
Какие инструменты проверяют стиль и качество Python-кода?
Линтеры и форматтеры — pycodestyle/flake8 (проверки PEP 8), pylint (стиль и логика), black (авто-форматтер) и mypy (статическая проверка типов) — ловят проблемы стиля и часть классов ошибок ещё до запуска кода.
Типичные ошибки
- ✗Считать чистый прогон
pylint/mypyдоказательством корректности логики и потому не писать поведенческие тесты - ✗Полагать, что
mypyпроверяет поведение во время выполнения, а не только статические аннотации типов
Уточняющие вопросы
- →Чем
blackиflake8различаются по тому, что они проверяют? - →Почему
mypyдополняет набор runtime-тестов, а не заменяет его?
JuniorТеорияЧастоЧто такое пирамида тестирования?
Что такое пирамида тестирования?
Модель состава тестов: много быстрых изолированных юнит-тестов в основании, меньше интеграционных в середине и немного медленных end-to-end тестов наверху. Она смещает покрытие к дешёвым и быстрым тестам.
Типичные ошибки
- ✗Переворачивать пирамиду, полагаясь в основном на медленные end-to-end тесты
- ✗Понимать её как ранжирование по важности, а не по количеству и скорости
Уточняющие вопросы
- →Почему юнит-тесты предпочтительнее в основании, чем end-to-end тесты?
- →Что такое «testing trophy» и чем он отличается от пирамиды?
MiddleТеорияЧастоЧем отличаются юнит-тесты от интеграционных?
Чем отличаются юнит-тесты от интеграционных?
Юнит-тест проверяет один изолированный модуль с замоканными зависимостями — быстро и с точной локализацией. Интеграционный проверяет, что несколько модулей или модуль с реальной БД или API работают вместе.
Типичные ошибки
- ✗Называть тест «юнитом», когда он всё ещё ходит в реальную БД или сеть
- ✗Считать, что интеграционные тесты должны мокать каждую зависимость, как юнит-тесты
Уточняющие вопросы
- →Где находятся end-to-end тесты относительно этих двух?
- →Почему юнит-тесты локализуют сбой лучше, чем интеграционные?
MiddleТеорияИногдаКак тестировать функцию, вызывающую нестабильный внешний сервис?
Как тестировать функцию, вызывающую нестабильный внешний сервис?
Не ходите в реальную сеть из юнит-теста. Внедрите клиент как зависимость или подмените через patch, подставив мок с управляемыми ответами — таймауты и коды ошибок тоже — чтобы детерминированно проверить каждую ветку.
Типичные ошибки
- ✗Позволять юнит-тесту делать реальный сетевой вызов к нестабильному сервису
- ✗Мокать только успешный путь и не проверять ветки таймаута и кодов ошибок
Уточняющие вопросы
- →Как смоделировать таймаут и ответ HTTP 500 с помощью мока?
- →Где всё же уместен реальный интеграционный тест против этого сервиса?
SeniorТеорияИногдаКогда внедрение зависимости предпочтительнее мокирования через patch?
Когда внедрение зависимости предпочтительнее мокирования через patch?
Предпочитайте внедрение, когда вы управляете дизайном: передача соавторов делает подмену явной и устойчивой к рефакторингу. patch залезает в модуль и заменяет имена — удобно для легаси-кода, но хрупко к путям импорта.
Типичные ошибки
- ✗Считать внедрение и мокирование взаимоисключающими, а не дополняющими
- ✗Полагать, что цели
patchпереживут перенос или переименование модуля без правок
Уточняющие вопросы
- →Как внедрение через конструктор улучшает тестируемость против глобалей уровня модуля?
- →Когда
patch— единственный практичный вариант для легаси-кода?