Модуль requests в Python: установка и работа
Модуль requests в Python — это HTTP-библиотека, которая позволяет легко отправлять HTTP-запросы. Обычно вы используете модуль запросов для работы и вызова API с удаленного сервера.
- Сценарий
- Выполнение вызова API с помощью модуля Requests
- Создание тестового модуля
- Имитирование модуля запросов
Сценарий
В демонстрационных целях мы будем использовать общедоступный API, предоставленный jsonplaceholder.typicode.com:
https://jsonplaceholder.typicode.com/
Чтобы выполнить вызов API, применяем метод Requests для отправки метода HTTP GET в следующую конечную точку:
https://jsonplaceholder.typicode.com/albums/1
Он вернет данные JSON в следующем формате:
{ "userId": 1, "id": 1, "title": "quidem molestiae enim" }
Поскольку модуль Requests не является встроенным модулем, вам необходимо установить его, выполнив следующую команду pip:
pip install requests
Выполнение вызова API с помощью модуля Requests
Следующий код определяет новый модуль под названием album.py с функцией find_album_by_id(), которая возвращает альбом по идентификатору:
import requests def find_album_by_id(id): url = f'https://jsonplaceholder.typicode.com/albums/{id}' response = requests.get(url) if response.status_code == 200: return response.json()['title'] else: return None
Как это работает.
- Сначала отформатируйте конечную точку API, включающую параметр id:
url = f'https://jsonplaceholder.typicode.com/albums/{id}'
- Во-вторых, вызовите функцию get() модуля Requests, чтобы получить объект Response:
response = requests.get(url)
- В-третьих, вызовите метод json() объекта ответа, если вызов API удался:
if response.status_code == 200: return response.json()['title'] else: return None
Функция response.json() возвращает словарь, представляющий данные JSON.
Создание тестового модуля
Мы создадим тестовый модуль test_album.py, который проверит функции модуля album.py:
import unittest from album import find_album_by_id class TestAlbum(unittest.TestCase): pass
Имитирование модуля запросов
Функция find_album_by_id() имеет две зависимости:
- Метод get() модуля Requests
- Объект Response, возвращаемый функцией get().
Итак, чтобы протестировать функцию find_album_by_id(), вам необходимо:
- Сначала измените модуль запросов и вызовите функцию get()(mock_requests).
- Во-вторых, имитируйте возвращаемый объект ответа.
Другими словами, методock_requests.get() возвращает объект ложного ответа.
Чтобы имитировать модуль запросов, вы можете использовать функцию patch(). Предположим, что Mock_requests — это макет модуля Requests.
Mock_requests.get() должен вернуть макет ответа. Чтобы имитировать ответ, вы можете использовать класс MagicMock модуля unittest.mock.
Ниже показано, как протестировать find_album_by_id() с помощью тестового метода test_find_album_by_id_success():
import unittest from unittest.mock import MagicMock, patch from album import find_album_by_id class TestAlbum(unittest.TestCase): @patch('album.requests') def test_find_album_by_id_success(self, mock_requests): # mock the response mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = { 'userId': 1, 'id': 1, 'title': 'hello', } # specify the return value of the get() method mock_requests.get.return_value = mock_response # call the find_album_by_id and test if the title is 'hello' self.assertEqual(find_album_by_id(1), 'hello')
Как это работает.
- Сначала исправьте модуль Requests как объект макета_requests:
@patch('album.requests') def test_find_album_by_id_success(self, mock_requests): # ...
- Во-вторых, имитируйте ответ функции get(), используя класс MagicMock. В этом методе тестирования мы указываем код состояния 200 и return_value функции json() как жестко запрограммированное значение:
mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = { 'userId': 1, 'id': 1, 'title': 'hello', }
- В-третьих, используйте «mock_response» в качестве возвращаемого значения функции get():
mock_requests.get.return_value = mock_response
- Наконец, проверьте, соответствует ли название альбома тому, которое мы указали в return_value макета_ответа:
self.assertEqual(find_album_by_id(1), 'hello')
Запустите тест:
python -m unittest -v
Выход:
test_find_album_by_id_success(test_album.TestAlbum) ... ok ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
Используя тот же метод, вы также можете протестировать функцию find_album_by_id() в случае неудачи:
import unittest from unittest.mock import MagicMock, patch from album import find_album_by_id class TestAlbum(unittest.TestCase): @patch('album.requests') def test_find_album_by_id_success(self, mock_requests): # mock the response mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = { 'userId': 1, 'id': 1, 'title': 'hello', } # specify the return value of the get() method mock_requests.get.return_value = mock_response # call the find_album_by_id and test if the title is 'hello' self.assertEqual(find_album_by_id(1), 'hello') @patch('album.requests') def test_find_album_by_id_fail(self, mock_requests): mock_response = MagicMock() mock_response.status_code = 400 mock_requests.get.return_value = mock_response self.assertIsNone(find_album_by_id(1))
Выход:
test_find_album_by_id_fail(test_album.TestAlbum) ... ok test_find_album_by_id_success(test_album.TestAlbum) ... ok ---------------------------------------------------------------------- Ran 2 tests in 0.002s OK