Перейти к содержимому
На этой странице

Тестирование Python

Все темы Python Developer

Как устроены фикстуры pytest и их scope?

Фикстура готовит данные или ресурсы для теста. Её объявляют через @pytest.fixture, а тест запрашивает её по имени параметра. Фикстуры могут запрашивать другие фикстуры таким же способом.

scope задаёт время жизни фикстуры: function по умолчанию действует для одного теста, class для класса, module для модуля, package для пакета, session для всего прогона. Широкий scope позволяет переиспользовать ресурс, но общее изменяемое состояние может связать тесты друг с другом.

В фикстуре с yield подготовка выполняется до него, а очистка после него, когда заканчивается scope. Очистка выполняется и при падении теста, если фикстура дошла до yield.

import sqlite3

import pytest


@pytest.fixture
def db():
    connection = sqlite3.connect(":memory:")
    yield connection
    connection.close()


def test_query(db):
    assert db.execute("SELECT 1").fetchone() == (1,)

Здесь каждый тест получает отдельное соединение, которое закрывается после теста.


Чем pytest отличается от unittest и как выбрать?

unittest входит в стандартную библиотеку, использует классы и собственные методы assertions. pytest дает обычные assert, мощные фикстуры, параметризацию и большую экосистему плагинов; он также умеет запускать многие тесты unittest. Для нового проекта чаще удобнее pytest. Существующий стабильный набор не стоит переписывать без измеримой выгоды: фреймворки можно применять совместно и мигрировать постепенно. Хороший тест проверяет наблюдаемое поведение и сохраняет понятную причину падения при изменении реализации.


Когда Mock помогает, а когда делает тест хрупким?

Mock полезен на границе с дорогой или нестабильной зависимостью: сетью, часами, внешним клиентом. Он позволяет воспроизвести отказ и проверить важное взаимодействие. Патчить нужно имя там, где его использует тестируемый модуль. Тест становится хрупким, когда проверяет внутренние вызовы вместо результата или воспроизводит реализацию реального сервиса. Контракт границы подтверждают интеграционными тестами, а autospec помогает ловить неверные сигнатуры. Хороший тест проверяет наблюдаемое поведение и сохраняет понятную причину падения при изменении реализации.


Что измеряет test coverage и чего он не доказывает?

Coverage показывает, какие строки и, при branch coverage, ветви исполнялись тестами. coverage.py или pytest-cov помогают найти непройденные пути и отслеживать регресс порога. Высокий процент не доказывает правильность: тест может выполнить строку без полезного assertion, не проверить границы данных и пропустить ошибочный сценарий. Метрику используют как карту пробелов, а не как самостоятельную цель качества. Хороший тест проверяет наблюдаемое поведение и сохраняет понятную причину падения при изменении реализации.


Как параметризовать тест в pytest?

В pytest используют @pytest.mark.parametrize('input,expected', [...]); каждый набор становится отдельным запуском теста. Понятные id упрощают отчет, а таблица хорошо подходит одному поведению с разными входами и ожиданиями. Если случаи требуют разной подготовки, разных assertions или объясняют разные правила, их лучше разделить: слишком широкая параметризация прячет смысл и усложняет диагностику. Хороший тест проверяет наблюдаемое поведение и сохраняет понятную причину падения при изменении реализации.


Как использовать return_value, side_effect и autospec у Mock?

return_value задает обычный результат mock-вызова. side_effect может быть функцией, последовательностью результатов или исключением. assert_called_once_with проверяет важный контракт вызова. spec ограничивает доступ известными атрибутами, а autospec дополнительно учитывает сигнатуры. patch заменяет имя в модуле-потребителе, а не обязательно в модуле, где объект определен. Эти средства не заменяют проверку реальной интеграции. Хороший тест проверяет наблюдаемое поведение и сохраняет понятную причину падения при изменении реализации.


Что показывает пирамида тестирования?

Пирамида тестирования показывает экономику набора: быстрых локальных тестов обычно много, интеграционных меньше, а сквозных сценариев еще меньше, потому что они медленнее и сложнее диагностируются. Это ориентир, а не требование процентов. Уровни дополняют друг друга: unit-тест проверяет правило, интеграционный подтверждает контракт с БД или сервисом, а end-to-end защищает ключевой пользовательский путь. Хороший тест проверяет наблюдаемое поведение и сохраняет понятную причину падения при изменении реализации.

Собеседования: Python

Смотри записи интервью, узнай, какие вопросы задают и как отвечают кандидаты.

Вопросы и ответы

Не нашли ответ? Напишите мне в чат. Я делаю Шпаргалку и сам отвечаю на сообщения. Расскажите, что не работает или чего вам не хватает. Может, смогу сразу взять это в работу.

Откуда взяты вопросы?

Из реальных собеседований. Основой подборки стал опыт Вадима Новосёлова: он проходил интервью и записывал вопросы. Подробнее о материалах.

Насколько эти вопросы актуальны?

Эти вопросы встречались нам на реальных собеседованиях в 2025 году. Мы регулярно проходим собеседования и пополняем подборку новыми вопросами. Основы профессии и ключевые технологии остаются востребованными годами, а детали конкретных инструментов и версий стоит сверять с текущей документацией.

На какой уровень рассчитана подборка?

Мы проходили собеседования на вакансии уровня Middle+, а иногда и на Senior-позиции. Вопросы из этих интервью вошли в подборку. Направления работы: Python-разработчик, Backend-разработчик на Python. Глубина обсуждения зависит от вакансии: будь готов объяснить основную идею, привести практический пример и разобрать ограничения и альтернативы решения.

Этот вопрос точно будет на моём собеседовании?

Гарантии нет: набор вопросов зависит от компании, задач команды, уровня вакансии и самого интервьюера. Эти вопросы уже встречались на реальных собеседованиях, но на твоём интервью ту же тему могут проверить другой формулировкой, практической задачей или обсуждением твоего опыта. Используй подборку, чтобы разобраться в теме: объясняй идею своими словами, приводи примеры и готовься обсудить ограничения и альтернативы решения. Так будет проще ответить и на знакомый вопрос, и на неожиданные уточнения.