pytest monkeypatch: как проверять переменные окружения без изменения настроек компьютера

pytest monkeypatch: как проверять переменные окружения без изменения настроек компьютера
Содержание статьи

В тесте pytest переменную окружения можно установить через monkeypatch.setenv(), а убрать через monkeypatch.delenv(). После завершения запрашивающего теста или фикстуры изменения отменяются. На Mentoring.digital проверим три состояния настройки без записи в постоянные параметры системы.

Функция с явным моментом чтения

# settings_demo.py
import os

def read_retries():
    return int(os.environ.get("APP_RETRIES", "3"))

Это намеренно простой контракт: отсутствие ключа означает три попытки, корректная строка преобразуется в число, некорректная даёт ValueError. Для настоящего сервиса дополнительно понадобятся ограничения диапазона и понятное сообщение пользователю.

Важно, что функция читает окружение при вызове. Если сохранить значение в глобальную константу во время импорта модуля, поздняя подмена окружения не изменит уже вычисленную константу. Сначала выясните, где и когда читается настройка, и только потом выбирайте точку подмены.

Три теста без зависимости от окружения разработчика

# test_settings_demo.py
import pytest
from settings_demo import read_retries

def test_explicit_value(monkeypatch):
    monkeypatch.setenv("APP_RETRIES", "5")
    assert read_retries() == 5

def test_missing_value(monkeypatch):
    monkeypatch.delenv("APP_RETRIES", raising=False)
    assert read_retries() == 3

def test_invalid_value(monkeypatch):
    monkeypatch.setenv("APP_RETRIES", "many")
    with pytest.raises(ValueError):
        read_retries()

raising=False позволяет удалить ключ и тогда, когда его изначально нет. Иначе тест на значение по умолчанию мог бы зависеть от компьютера, на котором его запускают. Первый тест тоже не полагается на случайную пользовательскую настройку: он явно задаёт своё условие.

Почему ручная запись хуже

При прямой записи в os.environ нужно самостоятельно восстановить прежнее значение, включая случай, когда ключ отсутствовал. Если проверка завершится исключением до восстановления, следующий тест получит изменённую среду. Фикстура помогает связать время жизни подмены с тестом.

Это не значит, что она изолирует весь компьютер или произвольный внешний процесс. В данном примере изменяется окружение процесса с тестом. Постоянные настройки Windows, оболочки и серверной службы не редактируются.

Что ещё стоит проверить в реальном проекте

Согласуйте поведение для пустой строки, нуля и отрицательного числа. Не превращайте каждую неожиданную настройку в значение по умолчанию: иногда правильнее прекратить запуск с понятной ошибкой. Это решение зависит от того, насколько опасно работать с неверной конфигурацией.

Если функция использует кэш настроек, тест должен учитывать его жизненный цикл. Не пытайтесь исправлять неверную точку подмены многократной перезагрузкой всех модулей. Выделенная функция чтения конфигурации часто даёт более понятную границу для проверки.

Как запустить и оценить результат

python -m pytest -q test_settings_demo.py

Сначала проверьте, что тесты работают независимо от исходного значения ключа. Затем добавляйте ограничения вашего приложения. При разборе фикстур и конфигурации поможет наставник по Python. Тестирование этого примера не подтверждает корректность настроек какого-либо рабочего сервиса.

Похожие статьи по данной теме