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-запитів і подивимось, як гарантувати коректність відправки даних.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ