Тестирование API с Playwright и Python (часть 1)

Подпишитесь на наш ТЕЛЕГРАМ КАНАЛ ПО АВТОМАТИЗАЦИИ ТЕСТИРОВАНИЯ

Перевод статьи «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.

⭐️ Содержание:

  1. Настройка Python проекта в PyCharm
  2. Установка зависимостей в Plawright и Pytest
  3. Моделирование API
  4. Написание тестовых скриптов
  5. Запуск тестов
  6. Управление скриптами 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 =================================================================================

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

🔥 Какой была ваша первая зарплата в QA и как вы искали первую работу? 

Мега обсуждение в нашем телеграм-канале о поиске первой работы. Обмен опытом и мнения.

Читать в телеграм

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *