JavaRush /Курсы /Модуль 4: FastAPI /Тестирование GET-запросов с использованием TestClient

Тестирование GET-запросов с использованием TestClient

Модуль 4: FastAPI
5 уровень , 2 лекция
Открыта

GET-запросы — это основа большинства API. Они позволяют нам запрашивать ресурсы и данные с сервера. Например, доступ к списку пользователей, информации о продукте или данных погоды. Однако представьте, что сервер неожиданно начал возвращать недостоверную информацию или, ещё хуже, HTTP-ошибку вместо ожидаемого JSON-ответа. Тестирование GET-запросов позволяет предотвратить подобные недоразумения, обеспечив корректность работы API.

В реальных проектах тестирование GET-запросов помогает:

  1. Проверить, что эндпоинты работают правильно и возвращают ожидаемые данные.
  2. Убедиться, что структура ответа соответствует документации.
  3. Защититься от случайных изменений в коде, которые могут сломать функциональность.

Использование TestClient из FastAPI

FastAPI предоставляет встроенный инструмент для тестирования — TestClient. Он позволяет взаимодействовать с приложением FastAPI как с настоящим сервером, но без необходимости запускать его на реальном хосте. Это значит, что тесты выполняются быстро и изолированно, обеспечивая контроль над их средой.

TestClient строится на основе библиотеки requests, поэтому он сохраняет аналогичный синтаксис для отправки запросов.


Настройка TestClient

Первым делом нужно создать экземпляр TestClient, который будет взаимодействовать с вашим приложением FastAPI. Рассмотрим базовый пример:


from fastapi import FastAPI
from fastapi.testclient import TestClient

# Создаём тестируемое приложение
app = FastAPI()

@app.get("/users")
async def get_users():
    return {"users": ["Alice", "Bob", "Charlie"]}

# Создаём клиент для тестирования
client = TestClient(app)

def test_get_users():
    response = client.get("/users")  # Отправляем GET-запрос
    assert response.status_code == 200  # Проверяем, что статус ответа — 200
    assert response.json() == {"users": ["Alice", "Bob", "Charlie"]}  # Проверяем тело ответа

Здесь мы видим:

  1. Приложение FastAPI с простым эндпоинтом /users, возвращающим список пользователей.
  2. Экземпляр TestClient, взаимодействующий с приложением.
  3. Тест, проверяющий успешный отклик эндпоинта.

На этом этапе мы уже можем запустить тест и убедиться, что всё работает. Но давайте углубимся в детали.


Написание тестов для GET-запросов

Статус ответа (status_code) — это первое, что необходимо проверить. Статусы вроде 200 OK, 404 Not Found или 500 Internal Server Error дают представление о том, как сервер обработал запрос.

Пример проверки статуса:


def test_status_code():
    response = client.get("/users")
    assert response.status_code == 200  # Всё прошло успешно

Если ваш API возвращает другой статус (например, 404), это может указывать на проблему с маршрутизацией или логикой обработки запроса.


Проверка структуры и содержания ответа

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

Пример проверки JSON-ответа:


def test_response_content():
    response = client.get("/users")
    assert response.json() == {"users": ["Alice", "Bob", "Charlie"]}  # Ожидаемое содержимое

Если структура ответа может меняться, можно использовать более гибкий подход с ключами:


def test_response_keys():
    response = client.get("/users")
    data = response.json()
    assert "users" in data  # Проверяем наличие ключа "users"
    assert isinstance(data["users"], list)  # Проверяем тип данных: должен быть список

Тестирование параметров запроса

Иногда GET-запросы требуют параметров, например, для фильтрации или сортировки данных. FastAPI поддерживает передачу параметров через строку запроса (query parameters).

Пример API с параметрами:


@app.get("/users")
async def get_users(filter: str = None):
    users = ["Alice", "Bob", "Charlie"]
    if filter:
        users = [user for user in users if filter.lower() in user.lower()]
    return {"users": users}

Тест проверки параметров:


def test_query_parameters():
    response = client.get("/users?filter=Ali")  # Передаём параметр filter
    assert response.status_code == 200
    assert response.json() == {"users": ["Alice"]}  # Ожидаем отфильтрованный список

Проверка различных сценариев

Проверяйте API на разные условия использования. Например, пустые запросы или запросы с невалидными параметрами:


def test_empty_response():
    response = client.get("/users?filter=Zoe")  # Нет пользователей с таким именем
    assert response.status_code == 200
    assert response.json() == {"users": []}  # Пустой список

def test_invalid_query():
    response = client.get("/users?unknown_param=1")  # Неизвестный параметр
    assert response.status_code == 200  # Эндпоинт всё ещё должен работать
    assert response.json() == {"users": ["Alice", "Bob", "Charlie"]}  # Игнорируем лишние параметры

Организация тестов

При большом количестве тестов важно поддерживать их структуру. Распределяйте тесты по файлам или группам в зависимости от тестируемой области.

Пример структуры тестов:


tests/
    test_users.py
    test_products.py
    test_auth.py

Типичные ошибки при тестировании GET-запросов

  1. Тесты проверяют только статус ответа. Это важно, но недостаточно. Убедитесь, что возвращаемые данные соответствуют ожиданиям.
  2. Игнорирование граничных случаев. Проверяйте API на пустые запросы, несуществующие параметры и запретные действия.
  3. Недостаточная изоляция тестов. Если тесты зависят от внешних данных или содержимого базы, они могут быть нестабильными. Используйте фикстуры для создания тестовых данных.

Практическая задача: тестируем простую API

Предположим, у нас есть API для получения списка книг:


@app.get("/books")
async def get_books():
    return {"books": ["1984", "Brave New World", "Fahrenheit 451"]}

Задачи:

  1. Напишите тест, проверяющий, что эндпоинт /books возвращает статус 200 и список книг.
  2. Напишите тест, который проверяет, что структура ответа содержит ключ books.

Решение:


def test_books_endpoint():
    response = client.get("/books")
    assert response.status_code == 200
    assert response.json() == {"books": ["1984", "Brave New World", "Fahrenheit 451"]}

def test_books_structure():
    response = client.get("/books")
    data = response.json()
    assert "books" in data
    assert isinstance(data["books"], list)

Теперь мы в курсе, как тестировать GET-запросы в FastAPI с помощью TestClient. В следующей лекции мы разберём тестирование POST-запросов и узнаем, как гарантировать корректность отправки данных.

1
Задача
Модуль 4: FastAPI, 5 уровень, 2 лекция
Недоступна
Тестирование эндпоинта с параметрами запроса
Тестирование эндпоинта с параметрами запроса
1
Задача
Модуль 4: FastAPI, 5 уровень, 2 лекция
Недоступна
Тестирование обработки ошибок в GET-запросе
Тестирование обработки ошибок в GET-запросе
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ