---
title: Тестирование Python
questionDates:
  q-pytest-fixtures-scope: '2026-10-01'
  q-transfer-0164: '2026-10-01'
  q-transfer-0166: '2026-10-01'
  q-transfer-0167: '2026-10-01'
  q-transfer-0168: '2026-10-01'
  q-transfer-0169: '2026-10-01'
  q-transfer-0170: '2026-10-01'
seo:
  description: >-
    Тема «Тестирование Python» для собеседования Python Developer. Как устроены
    фикстуры pytest и их scope?
  title: Тестирование Python — Python Developer
---

[Все темы Python Developer](/prep/python-developer)

## Как устроены фикстуры pytest и их scope? [#q-pytest-fixtures-scope]

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

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

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

```python
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,)
```

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

:::note[Ссылки для изучения]

1. [Фикстуры pytest: зависимости, scope и очистка через yield — русская документация pytest 7.2](https://pythondoc.ru/docs/pytest/7.2/how-to/fixtures/)
2. [Фикстуры и scope. Артём Шумейко, с 2:48](https://www.youtube.com/watch?v=OIvZ0oHl7rA&t=168s)

:::

---

## Чем pytest отличается от unittest и как выбрать? [#q-transfer-0164]

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

:::note[Ссылки для изучения]

1. [Unittest и pytest: классы, assert и повторно используемые фикстуры — Дейн Хиллард](https://habr.com/ru/companies/otus/articles/580212/)
   :::

---

## Когда Mock помогает, а когда делает тест хрупким? [#q-transfer-0166]

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

:::note[Ссылки для изучения]

1. [Когда моки делают тесты хрупкими: поведение вместо внутренних вызовов — Авито](https://habr.com/ru/companies/avito/articles/1001170/)
   :::

---

## Что измеряет test coverage и чего он не доказывает? [#q-transfer-0167]

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

:::note[Ссылки для изучения]

1. [Покрытие строк и ветвей: почему 100% не означает полную проверку — Positive Technologies](https://habr.com/ru/companies/pt/articles/323294/)
   :::

---

## Как параметризовать тест в pytest? [#q-transfer-0168]

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

:::note[Ссылки для изучения]

1. [Параметризация pytest: входные данные и ожидаемый результат в таблице — Дейн Хиллард](https://habr.com/ru/companies/otus/articles/580212/)
2. [Параметризация тестов. Артём Шумейко, с 0:06](https://www.youtube.com/watch?v=qV4hVzHl6UM&t=6s)

:::

---

## Как использовать `return_value`, `side_effect` и autospec у Mock? [#q-transfer-0169]

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

:::note[Ссылки для изучения]

1. [Mock: return_value, side_effect и проверка сигнатур через autospec — документация Python](https://pythondoc.ru/docs/python/3.10/library/unittest.mock/#quick-guide)
   :::

---

## Что показывает пирамида тестирования? [#q-transfer-0170]

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

:::note[Ссылки для изучения]

1. [Пирамида тестирования: разные уровни и стоимость набора — Хам Воке](https://habr.com/ru/articles/358950/)
   :::
