Полезняшка: responses

Опубликовано 09 March 2016 в Python

Если вы используете в своем проекте requests, то наверняка сталкиваетесь с проблемами тестирования. На помощь придет библиотека responses, которая позволяет делать моки ответов вызовов requests.

Мы в своем проекте используем эту библиотеку не так давно. Хотя из-за особенности окружения проекта мы ходим много в огромное количество REST API смежных сервисов. И до того, как requests попалась нам на глаза, код тестов представлял из себя нечто невообразимое трудно читаемое.

Пользоваться библиотекой невероятно просто. Для иллюстрации пара примеров из документации:

Пример 1

import responses
import requests


@responses.activate
def test_my_api():
    responses.add(responses.GET, 'http://twitter.com/api/1/foobar',
    json={"error": "not found"}, status=404)
    resp = requests.get('http://twitter.com/api/1/foobar')
    assert resp.json() == {"error": "not found"}
    assert len(responses.calls) == 1
    assert responses.calls[0].request.url == 'http://twitter.com/api/1/foobar'
    assert responses.calls[0].response.text == '{"error": "not found"}'

Пример 2

import responses
import requests


def test_my_api():
    with responses.RequestsMock() as rsps:
        rsps.add(responses.GET, 'http://twitter.com/api/1/foobar',
        body='{}', status=200,
        content_type='application/json')
        resp = requests.get('http://twitter.com/api/1/foobar')
        assert resp.status_code == 200
    # outside the context manager requests will hit the remote server
    resp = requests.get('http://twitter.com/api/1/foobar')
    resp.status_code == 404

Настоятельно рекомендую попробовать использовать в тестах responses. Местами мы наблюдаю неожиданный эффект: если пользоваться в тестах этой библиотекой, то часть кода, которая использует requests, можно переписать более внятно и компактно без оглядки на то, что какую-то часть нужно будет мокать для тестов.

---
Возник вопрос? Мне всегда можно написать в Twitter: avkorablev