Подпишитесь на наш ТЕЛЕГРАМ КАНАЛ ПО АВТОМАТИЗАЦИИ ТЕСТИРОВАНИЯ
Перевод статьи «API Testing: Playwright and Python (Part 1)».
Playwright — это современная библиотека для автоматизации браузеров от Microsoft, которая, работает на Node.js и позволяет легко имитировать действия пользователей в популярных браузерах: Chromium, Firefox и WebKit. Playwright поддерживает JavaScript, Python и Java, при этом предлагая простой и удобный API.
🍀 Хотя основная область применения Playwright — это тестирование пользовательского интерфейса, его возможности этим не ограничиваются. С его помощью можно выполнять HTTP запросы и анализировать ответы, что делает его полезным инструментом для тестирования API.
В этой статье мы напишем тестовые скрипты для автоматизации POST запросов с помощью Playwright и Pytest.
⭐️ Содержание:
- Настройка Python проекта в PyCharm
- Установка зависимостей в Plawright и Pytest
- Моделирование API
- Написание тестовых скриптов
- Запуск тестов
- Управление скриптами Pythonistas Way (часть 2) 😃
Настройка проекта Python с помощью Pycharm
- Скачайте PyCharm по ссылке и установите интерпретатор Python3 на свой компьютер.
- Создайте новый проект, используя виртуальное окружение Python3 (venv).
После базовой настройки структура проекта будет выглядеть следующим образом 👇

Добавьте зависимости Plawright и Pytest
Создайте в корне проекта файл и добавьте в него следующие зависимости:
📁requirements.txt
pytest-playwright pytest playwright
💻 Чтобы установить все необходимые зависимости непосредственно в ваше виртуальное окружение, выполните следующую команду в терминале PyCharm
pip install -r requirements.txt
Моделирование API
Рассмотрим принципы работы Playwright с API эндпоинтами.
Прежде чем погрузиться в работу с API, важно понять, что такое APIRequestContext.
APIRequestContext: это класс, представляющий контекст HTTP запросов для выполнения API вызовов. Он предоставляет высокоуровневый API для отправки HTTP запросов и получения ответов в ваших API тестах.
Класс APIRequestContext является частью сетевого API Playwright и используется для перехвата и модификации HTTP запросов и ответов. Он позволяет:
- Изменять заголовки и тело запроса
- Добавлять query-параметры в URL запроса
- Мокать ответы сервера для тестирования
- Измерять время выполнения запросов и ответов
✨ В Pytest мы будем использовать экземпляр APIRequestContext как фикстуру (pytest fixture), которую затем можно применять в тестовых скриптах.
Создадим новый Python файл для добавления этих настроек.
🍀 Всегда добавляйте префикс или суффикс «test» к именам Python файлов и тестовых методов, чтобы pytest мог легко находить ваши скрипты для выполнения тестов.
test_playwright_api.py
Сначала импортируем необходимые зависимости
import pytest from typing import Generator from playwright.sync_api import Playwright, APIRequestContext
Мы будем использовать демо API https://reqres.in для наших тестовых скриптов.

Теперь настроим взаимодействие с API пользователей через APIRequestContext. Для этого создадим pytest-фикстуру с областью видимости session — она будет инициализировать контекст запросов один раз для всех тестов👇
Эта фикстура возвращает контекст запроса типа APIRequestContext, который можно использовать для выполнения CRUD операций.
@pytest.fixture(scope="session")
def user_api_request_context(playwright: Playwright) -> Generator[APIRequestContext, None, None]:
request_context = playwright.request.new_context(
base_url="https://reqres.in"
)
yield request_context
request_context.dispose()
Написание тестовых скриптов
Мы напишем 3 скрипта: 2 для проверки позитивных сценариев (POST и GET запросы) и 1 для негативного сценария GET запроса.
Здесь мы добавим еще одну фикстуру для автоматической генерации ID пользователей, чтобы эти ID можно было использовать в GET запросах.
@pytest.fixture(scope="session")
def user_ids():
ids = []
yield ids
✅ POST /api/users
В этом методе мы используем фикстуру user_api_request_context для выполнения API вызовов и фикстуру user_ids для хранения ID для дальнейших проверок.
def test_create_user(user_api_request_context: APIRequestContext, user_ids) -> None:
payload = {
"name": "Ramadheer Singh",
"job": "Rangdari"
}
response = user_api_request_context.post(url=f"/api/users", data=payload)
assert response.ok
json_response = response.json()
print("Create User API Response:\n{}".format(json_response))
assert json_response["name"] == payload.get("name")
user_ids.append(json_response["id"])
🚩 GET /api/users/{user_id} — Пользователь не найден
def test_get_user_not_found(user_api_request_context: APIRequestContext, user_ids) -> None:
response = user_api_request_context.get(url=f"/api/users/{user_ids[0]}")
assert response.status == 404
json_response = response.json()
print("Get User API Response - User Not Found:\n{}".format(json_response))
✅ GET /api/users/{user_id} —Успешный сценарий
Здесь я использую валидный userId — «2» для получения данных.
def test_get_user_happy_flow(user_api_request_context: APIRequestContext) -> None:
response = user_api_request_context.get(url=f"/api/users/2")
assert response.status == 200
json_response = response.json()
print("Get User API Response - Happy Flow:\n{}".format(json_response))
assert json_response["data"]["id"] == 2
Финальный код 👇
import pytest
from typing import Generator
from playwright.sync_api import Playwright, APIRequestContext
@pytest.fixture(scope="session")
def user_ids():
ids = []
yield ids
@pytest.fixture(scope="session")
def user_api_request_context(playwright: Playwright) -> Generator[APIRequestContext, None, None]:
request_context = playwright.request.new_context(
base_url="https://reqres.in"
)
yield request_context
request_context.dispose()
def test_create_user(user_api_request_context: APIRequestContext, user_ids) -> None:
payload = {
"name": "Ramadheer Singh",
"job": "Rangdari"
}
response = user_api_request_context.post(url=f"/api/users", data=payload)
assert response.ok
json_response = response.json()
print("Create User API Response:\n{}".format(json_response))
assert json_response["name"] == payload.get("name")
user_ids.append(json_response["id"])
def test_get_user_not_found(user_api_request_context: APIRequestContext, user_ids) -> None:
response = user_api_request_context.get(url=f"/api/users/{user_ids[0]}")
assert response.status == 404
json_response = response.json()
print("Get User API Response - User Not Found:\n{}".format(json_response))
def test_get_user_happy_flow(user_api_request_context: APIRequestContext) -> None:
response = user_api_request_context.get(url=f"/api/users/2")
assert response.status == 200
json_response = response.json()
print("Get User API Response - Happy Flow:\n{}".format(json_response))
assert json_response["data"]["id"] == 2
Запуск тестовых скриптов
Просто выполните следующую команду в терминале (лучше в терминале PyCharm, где зависимости доступны в python3 venv)
pytest -s
Что получилось👇

================================================================================ test session starts ================================================================================
platform darwin -- Python 3.9.6, pytest-7.3.1, pluggy-1.0.0
rootdir: /Users/abhilashsharma/Documents/learning/playwright/api-testing-playwright
plugins: base-url-2.0.0, playwright-0.3.3
collected 3 items
test_playwright_api.py Create User API Response:
{'name': 'Ramadheer Singh', 'job': 'Rangdari', 'id': '164', 'createdAt': '2023-04-25T05:52:36.141Z'}
.Get User API Response - User Not F>ыound:
{}
.Get User API Response - Happy Flow:
{'data': {'id': 2, 'email': 'janet.weaver@reqres.in', 'first_name': 'Janet', 'last_name': 'Weaver', 'avatar': 'https://reqres.in/img/faces/2-image.jpg'}, 'support': {'url': 'https://reqres.in/#support-heading', 'text': 'To keep ReqRes free, contributions towards server costs are appreciated!'}}
.
================================================================================= 3 passed in 1.47s =================================================================================
В следующей части мы обсудим, как лучше организовать скрипты и создать поддерживаемую структуру фреймворка.