О подключаемом расширении для pytest, позволяющем упростить написание тестов для кода, использующего вызовы requests.
В 2013 году Дэвид Крамер, работая над Sentry, основал замечательный проект responses, позволяющий имитировать ответы от внешних http-сервисов для запросов, сделанных через requests.

Тот же Дэвид три года спустя сообразил подключаемое расширение (плагин) для pytestpytest-responses. Суть работы плагина проста: в тестах по умолчанию запрещаются обращения через requests, предполагается, что для каждого теста нужно определить имитацию ответов, иначе он не пройдёт. А при помощи специального декоратора можно разрешить тесту походы наружу.

Одно время я пользовался эти расширением, но удобство работы оставляло желать лучшего. Вообще, у меня что-то не складывается с подходом «по умолчанию запрещено» в отношении к тестам. В прошлый раз из-за несогласия с таким подходом появился pytest-djangoapp, теперь вот — pytest-responsemock.

Некоторое время я пользовался responses в тестах напрямую, но сейчас перехожу на pytest-responsemock.
Для сравнения: перевод одного из тестов pythonz на новое расширение.

Итак, что предлагает pytest-responsemock.
В основе лежит фикстура response_mock, являющаяся менеджером контекста.
Ожидается, что блок кода, под данным менеджером содержит один или более вызовов requests, ответы на которые требуется имитировать.

    def for_test():
"""Работу этой функции мы будем проверять тестом."""
return requests.get('http://some.domain')

def test_me(response_mock):
"""Это наш тест. Он использует pytest-фикстуру response_mock."""

with response_mock('GET http://some.domain -> 200 :Nice', bypass=False):
# Ответы на обращения requests под данным менеджером
# будут сымитированы.
result = for_test()

# А вот и имитация в виде ответа:
assert result.ok
assert result.content == b'Nice'

Благодаря использованию контекстного менеджера мы можем подменять ответы только в определённых участках кода.

Кроме того, для случаев, когда нужно по какому-то условию отключить имитацию и заставить requests опросить реальный ресурс, существует необязательный параметр bypass (по умолчанию он False).

Основным параметром для менеджера является одно или более (для описания последовательных запросов) правил, сформулированных в виде строк, описывающих на какой запрос какой ответ требуется имитировать.
Формат строки правила прост: HTTP_МЕТОД URL -> КОД_СТАТУСА :ТЕЛО_ОТВЕТА

Чуть больше информации и примеров можно найти в файле с описанием.

pytest-responsemock разрабатывается открыто на GitHub, желающие могут внести лепту.

Тестируй удобно.

Категории

Область
Проект

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