Пишете ли юнит и интеграционные тесты
Что проверяют
Не факт написания тестов, а систему: что вы покрываете юнитами, что интеграцией, чем изолируете внешние границы и сколько бежит набор. Тесты, которые идут десять минут и иногда краснеют сами по себе, команда перестаёт запускать, и интервьюер проверяет, понимаете ли вы это.
Как отвечать
Разведите уровни. Юнит это чистая логика без сети, диска и базы, он должен занимать миллисекунды. Интеграционный проверяет настоящую границу: запрос в базу, публикацию в брокер, вызов соседнего сервиса. Раннер обычно pytest: фикстуры вместо setUp, параметризация вместо копий теста, маркеры для разделения быстрого и медленного набора.
Дальше расскажите про изоляцию. Внешний HTTP подменяется на уровне транспорта (responses для requests, respx для httpx), а не патчем в каждом модуле. База поднимается настоящая, той же версии, что в проде, например через testcontainers: SQLite вместо PostgreSQL даёт зелёные тесты там, где прод падает на типах и на блокировках. Каждый тест идёт в своей транзакции с откатом в конце.
Асинхронный код тестируется через pytest-asyncio, а приложение на FastAPI удобно дёргать httpx с ASGI-транспортом, не поднимая сервер.
Про моки скажите принцип: подменяются внешние границы, а не собственные модули. И про покрытие говорите не процентом, а тем, что критичные пути (деньги, права доступа, идемпотентность) закрыты, а отчёт нужен, чтобы находить незакрытое.
Где спотыкаются
Называют юнит-тестами всё подряд. Тест, который ходит в сеть и в базу, лежит в быстром наборе, и весь прогон начинает падать по чужим причинам.
Второе: путают, куда ставить mock.patch. Патчить надо путь, по которому объект импортирован в тестируемый модуль, а не место его определения. Тест зелёный, мок не подключился, реальный вызов ушёл наружу.
Третье: тесты делят состояние и зависят от порядка. Общая фикстура на модуль, datetime.now() внутри логики и случайные данные без фиксированного зерна дают набор, зелёный локально и красный в CI при параллельном запуске.