Важко уявити сучасний веб-додаток без POST-запитів. Створення користувачів, відправка форм, додавання товарів у корзину — усе це прив'язане до POST-запитів. Тому переконатися, що POST-запити вашого API працюють коректно, — одна з ключових задач. Сьогодні поговоримо про те, як протестувати цю функціональність у FastAPI з використанням Pytest.
POST-запити в більшості випадків пов'язані зі створенням нових об'єктів. Тому важливо переконатися, що:
- Дані, передані в тілі запиту, коректні і проходять валідацію.
- API повертає правильний статус-код і очікувані дані.
- Некоректні або відсутні дані викликають помилки (наприклад, статус 422 або 400).
- Дані дійсно зберігаються (у випадку інтеграції з базою даних).
Протестуємо все це на прикладі простого API для керування користувачами. Ваша задача — переконатися, що користувач створюється коректно, а при помилках повертаються відповідні HTTP-відповіді.
Підготовка даних для POST-запитів
Перш ніж братися за тестування, створимо простий ендпоінт для додавання користувачів. Якщо ви слідували попереднім лекціям, у вас вже має бути шаблон проєкту FastAPI. Якщо раптом нема — ось мінімальний приклад:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
# Визначаємо модель даних для користувача
class User(BaseModel):
id: int
name: str
email: str
# Сховище користувачів
users = []
@app.post("/users/")
async def create_user(user: User):
# Перевіряємо, чи існує користувач з таким email
if any(u.email == user.email for u in users):
raise HTTPException(status_code=400, detail="Email вже існує")
users.append(user)
return user
Цей ендпоінт:
- Приймає на вхід дані користувача в форматі JSON з полями
id,nameіemail. - Перевіряє, чи не існує користувача з таким самим
email. - Додає користувача в список
usersі повертає його.
Тепер, коли у нас є ендпоінт, перейдемо до написання тестів.
Написання тестів для POST-запитів
Почнемо з перевірки успішної відправки даних. Для цього ми використовуємо TestClient. Переконайтеся, що у вас встановлені pytest і ваш тестовий файл називається test_main.py (або аналогічно).
from fastapi.testclient import TestClient
from main import app # Імпортуємо наш додаток
client = TestClient(app)
def test_create_user():
# Дані для відправки
data = {
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com"
}
# Тестуємо POST-запит
response = client.post("/users/", json=data)
# Перевіряємо, що код відповіді 200
assert response.status_code == 200
# Перевіряємо, що дані в відповіді співпадають з відправленими
assert response.json() == data
У цьому тесті ми:
- Створили тестові дані.
- Відправили POST-запит через
client.post. - Переконалися, що сервер повернув статус 200.
- Порівняли дані у відповіді з відправленими.
Перевірка успішної відправки даних
Тепер ускладнимо тест, додавши перевірку на дублювання email. Наш ендпоінт має повертати помилку 400, якщо користувач з таким email вже існує.
def test_create_user_duplicate_email():
# Дані для відправки
data = {
"id": 1,
"name": "Jane Doe",
"email": "jane.doe@example.com"
}
# Перший успішний запит
response = client.post("/users/", json=data)
assert response.status_code == 200
# Другий запит з тим самим email
response = client.post("/users/", json=data)
# Перевіряємо, що сервер повернув помилку 400
assert response.status_code == 400
assert response.json() == {"detail": "Email вже існує"}
Цей тест показує, як можна перевірити обробку помилок на нашому сервері. Спробуйте дописати тести для інших сценаріїв, наприклад, для некоректних даних.
Валідація даних у відповіді після успішної відправки
Тепер додамо тест, який перевіряє, що дані дійсно валідовані. Наприклад, якщо email не переданий або має неправильний формат, сервер повинен відповісти помилкою 422 (Unprocessable Entity).
def test_create_user_invalid_data():
# Дані з некоректним email
data = {
"id": 2,
"name": "Invalid User",
"email": "not-an-email"
}
# Відправляємо запит
response = client.post("/users/", json=data)
# Перевіряємо, що сервер повернув помилку 422
assert response.status_code == 422
# Перевіряємо повідомлення про помилку
assert "value is not a valid email" in response.text
FastAPI автоматично валідуює дані на основі Pydantic-моделі, тому такі перевірки допомагають переконатися, що ваша валідація працює як слід.
Поради щодо написання тестів для складних POST-запитів
- Використовуйте фікстури: для підготовки даних використовуйте фікстури Pytest. Це робить тести більш читабельними і зручними в підтримці.
import pytest @pytest.fixture def user_data(): return { "id": 3, "name": "Fixture User", "email": "fixture@example.com" } def test_create_user_with_fixture(user_data): response = client.post("/users/", json=user_data) assert response.status_code == 200 assert response.json() == user_data - Перевіряйте граничні значення. Наприклад, якщо ваш API приймає тільки певну довжину рядка, протестуйте мінімальні/максимальні значення.
- Логуйте дані для дебагу. Якщо щось пішло не так, ви завжди можете вивести
response.json()абоresponse.status_code, щоб зрозуміти причину.
Реальне застосування
На співбесіді вас можуть запитати, як протестувати, що відправлений POST-запит не тільки повертає коректні дані, але й вносить зміни в базу даних. Відповідь: ви можете використовувати тестову базу (SQLite або іншу) і перевіряти дані напряму через ORM або raw-запит.
На практиці тестування POST-запитів допомагає виявляти несподівані баги в логіці обробки даних, управлінні транзакціями або валідації. Найчастіше такі баги спливають у продакшені, коли користувачі починають вводити дані типу "O_o". Тому тести — ваше спасіння!
Тепер, коли ви навчилися тестувати POST-запити, ви готові до складніших сценаріїв: працювати з базою даних, мокати сервіси і навіть тестувати аутентифікацію. Вперед до нових тестів!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ