> Писали ли вы тесты (Python)

Уровень: middle · Роль: backend · Язык: Python · Категория: Технические вопросы

Компании: Herbarium_Games, Ростелеком, Black Wall Group (BWG), mozen, ФедяИСамат

Стек: Python

> Пример ответа

Короткий ответ

Да, писал. В основном unit-тесты на pytest для бизнес-логики и интеграционные тесты для взаимодействия с БД и внешними сервисами. Использую моки для изоляции зависимостей, фикстуры для подготовки данных. Покрываю критичные пути и edge cases, стараюсь держать покрытие на уровне 70-80%. Также писал тесты для API-эндпоинтов через TestClient.

Подробное объяснение

В работе с Python-бэкендом тесты - обязательная часть процесса. Основной инструмент - pytest, потому что он гибкий, имеет богатую экосистему плагинов и удобные фикстуры. Для мокирования использую unittest.mock или pytest-mock.

Unit-тесты покрывают изолированную логику: валидацию, расчёты, обработку ошибок. Интеграционные тесты проверяют связку с реальной БД (часто на тестовой PostgreSQL через testcontainers или отдельную схему) и с внешними API через моки.

Для веб-фреймворков (FastAPI, Django) использую встроенные TestClient - это позволяет проверять эндпоинты без поднятия сервера. Важно тестировать не только happy path, но и негативные сценарии: невалидные входные данные, отсутствие ресурса, таймауты.

Также практикую параметризацию тестов для покрытия множества кейсов с минимальным дублированием кода. Для асинхронного кода использую pytest-asyncio или anyio.

На практике

В реальных проектах тесты пишу сразу вместе с кодом, а не после. Это помогает проектировать API и ловить ошибки на раннем этапе. Обычно структура такая:

  • tests/unit/ - изолированные тесты функций и классов
  • tests/integration/ - тесты с БД и внешними зависимостями
  • tests/api/ - тесты эндпоинтов

Для каждого бага сначала пишу тест, который воспроизводит проблему, потом чиню код. Это гарантирует, что баг не вернётся. В CI тесты запускаются на каждый pull request, плюс отдельно прогоняется проверка покрытия.

Пример кода

PYTHON
# tests/test_user_service.py
import pytest
from unittest.mock import Mock
from app.services import UserService
from app.exceptions import UserNotFound
@pytest.fixture
def user_repo():
return Mock()
@pytest.fixture
def service(user_repo):
return UserService(repo=user_repo)
def test_get_user_success(service, user_repo):
user_repo.get.return_value = {"id": 1, "name": "Alice"}
result = service.get_user(1)
assert result["name"] == "Alice"
user_repo.get.assert_called_once_with(1)
def test_get_user_not_found(service, user_repo):
user_repo.get.return_value = None
with pytest.raises(UserNotFound):
service.get_user(999)
@pytest.mark.parametrize("user_id,expected", [
(1, "Alice"),
(2, "Bob"),
])
def test_get_user_parametrized(service, user_repo, user_id, expected):
user_repo.get.return_value = {"id": user_id, "name": expected}
result = service.get_user(user_id)
assert result["name"] == expected

Как отвечать на собеседовании

Начните с конкретики: какие фреймворки и библиотеки использовали, какой тип тестов писали чаще. Приведите пример реального кейса, когда тест помог найти баг или спроектировать API. Упомяните, как организуете тестовую среду: отдельная БД, моки, фикстуры. Если есть опыт с CI - расскажите, как тесты встроены в процесс разработки.

Не ограничивайтесь общими словами "да, писал". Покажите понимание trade-off: что покрывать, а что нет, как балансировать скорость и надёжность. Если не писали определённый тип тестов (например, нагрузочные) - честно скажите, но подчеркните, что знаете, как они устроены.

Что проверяет интервьюер

Интервьюер оценивает:

  • реальный опыт, а не теоретические знания - конкретные примеры и детали
  • понимание, зачем нужны разные уровни тестов
  • умение изолировать зависимости через моки и фикстуры
  • способность писать читаемые и поддерживаемые тесты
  • знание типичных паттернов: параметризация, setup/teardown, обработка исключений
  • понимание, как тесты встраиваются в CI/CD

Типичные ошибки

  • Ответ "да, писал" без деталей - выглядит как отсутствие реального опыта
  • Путаница между unit и integration тестами
  • Использование реальной БД в unit-тестах - это замедляет и делает тесты нестабильными
  • Тестирование только happy path, игнорирование ошибок и граничных случаев
  • Слишком много моков - тест перестаёт проверять реальное поведение
  • Хрупкие тесты, зависящие от порядка выполнения или глобального состояния
  • Отсутствие понимания, зачем нужен assert_called_once_with и подобные проверки взаимодействий

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью