← Назад к вопросам

Как обрабатываешь ответы запросов?

2.0 Middle🔥 141 комментариев
#Теория тестирования

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Стратегия обработки ответов API в автоматизации тестирования

Обработка ответов HTTP-запросов — это фундаментальный аспект тестирования API, который я выстраиваю в многоуровневую систему валидации. Подход зависит от типа теста (позитивный/негативный), но всегда следует принципу детерминированности и полноты проверок.

Основные этапы обработки

1. Проверка HTTP-статуса кода Первым делом валидирую статус ответа, так как это индикатор успешности операции. Использую библиотечные assertion или кастомные проверки:

import pytest
import requests

def test_get_user_returns_200():
    response = requests.get('https://api.example.com/users/1')
    # Базовая проверка
    assert response.status_code == 200
    # Или с информативным сообщением
    assert response.status_code == 200, \
        f"Expected 200, got {response.status_code}. Response: {response.text}"

2. Валидация структуры ответа Проверяю соответствие фактической структуры ответа ожидаемой схеме (JSON Schema, контракту):

from jsonschema import validate

def test_user_schema():
    response = requests.get('https://api.example.com/users/1')
    schema = {
        "type": "object",
        "properties": {
            "id": {"type": "integer"},
            "name": {"type": "string"},
            "email": {"type": "string", "format": "email"}
        },
        "required": ["id", "name", "email"]
    }
    validate(instance=response.json(), schema=schema)

3. Проверка бизнес-логики и данных Сравниваю значения полей ответа с ожидаемыми данными, учитывая предварительно созданные тестовые данные:

def test_user_data_correctness():
    # Предварительно создали пользователя с известными данными
    test_user = {"id": 1, "name": "Test User", "email": "test@example.com"}
    
    response = requests.get('https://api.example.com/users/1')
    data = response.json()
    
    assert data["id"] == test_user["id"]
    assert data["name"] == test_user["name"]
    assert data["email"] == test_user["email"]
    # Или компактно
    assert data == test_user

4. Анализ заголовков (headers) Проверяю технические метаданные ответа, которые часто содержат критичную информацию:

def test_response_headers():
    response = requests.get('https://api.example.com/users')
    
    assert response.headers['Content-Type'] == 'application/json'
    assert 'Cache-Control' in response.headers
    assert response.headers['X-RateLimit-Limit'] == '100'

Продвинутые техники обработки

Кастомные валидаторы и обертки Создаю абстракции над библиотеками для повторного использования проверок:

class APIResponseValidator:
    def __init__(self, response):
        self.response = response
    
    def status_should_be(self, expected_status):
        assert self.response.status_code == expected_status
        return self  # Для цепочки вызовов
    
    def body_should_contain(self, **expected_fields):
        data = self.response.json()
        for key, value in expected_fields.items():
            assert data[key] == value
        return self
    
    def header_should_be(self, header_name, expected_value):
        assert self.response.headers[header_name] == expected_value
        return self

# Использование
def test_with_custom_validator():
    response = requests.get('https://api.example.com/users/1')
    (APIResponseValidator(response)
     .status_should_be(200)
     .body_should_contain(id=1, active=True)
     .header_should_be('Content-Type', 'application/json'))

Обработка ошибок и негативных сценариев Для проверки корректности обработки ошибок сервером:

def test_invalid_user_returns_404():
    response = requests.get('https://api.example.com/users/99999')
    
    assert response.status_code == 404
    error_data = response.json()
    assert 'error' in error_data
    assert error_data['error'] == 'User not found'
    assert 'timestamp' in error_data  # Проверяем дополнительные поля ошибки

Извлечение данных для последующих запросов Часто один тест подготавливает данные для другого:

def test_create_and_retrieve_user():
    # Создаем пользователя
    create_response = requests.post('https://api.example.com/users', 
                                   json={"name": "New User"})
    assert create_response.status_code == 201
    user_id = create_response.json()['id']
    
    # Используем ID для получения
    get_response = requests.get(f'https://api.example.com/users/{user_id}')
    assert get_response.json()['name'] == "New User"

Ключевые практики, которые я применяю:

  • Использую специализированные библиотеки (pytest, requests, jsonschema, pydantic для валидации)
  • Реализую паттерн "Response Object Model" — создаю классы-обертки для ответов
  • Логирую полные детали при падениях тестов для упрощения дебага
  • Тестирую edge cases — пустые ответы, массивы, вложенные структуры
  • Измеряю performance-метрики — время ответа, размер данных
  • Валидирую безопасность — отсутствие чувствительных данных в ответах
  • Использую контрактное тестирование для проверки соответствия спецификациям

Инструментарий

В зависимости от проекта и стека использую:

  • Для REST: requests + pytest + jsonschema
  • Для GraphQL: специализированные клиенты с валидацией по схемам
  • Для асинхронных API: aiohttp или httpx
  • Для генерации проверок: Swagger/OpenAPI валидаторы

Такой подход обеспечивает стабильность тестов, ясность отчетов и эффективное выявление регрессий. Каждый слой проверки служит определенной цели: от технической корректности ответа до соответствия бизнес-требованиям.

Как обрабатываешь ответы запросов? | PrepBro