Настраиваем контрактные тесты между Frontend и Backend Todo-приложения. Ловим breaking changes до продакшена
Применим contract testing к реальному Todo API: GET, POST, PUT, DELETE.
Цель: Создать полный набор контрактов для защиты API.
{
"endpoint": "GET /api/todos",
"query_params": {
"status": { "enum": ["all", "pending", "completed"] }
},
"response": {
"type": "array",
"items": {
"type": "object",
"required": ["id", "title", "completed"],
"properties": {
"id": { "type": "integer" },
"title": { "type": "string", "maxLength": 255 },
"completed": { "type": "boolean" },
"created_at": { "type": "string", "format": "date-time" }
}
}
}
}{
"endpoint": "POST /api/todos",
"request_body": {
"type": "object",
"required": ["title"],
"properties": {
"title": { "type": "string", "minLength": 1, "maxLength": 255 }
}
},
"response": {
"status_code": 201,
"body": {
"type": "object",
"required": ["id", "title", "completed"],
"properties": {
"id": { "type": "integer" },
"title": { "type": "string" },
"completed": { "type": "boolean" }
}
}
}
}# backend/tests/test_todo_contracts.py
import pytest
import jsonschema
import json
from pathlib import Path
CONTRACTS_DIR = Path(__file__).parent.parent / "contracts"
def load_contract(name):
"""Load contract schema"""
with open(CONTRACTS_DIR / f"{name}.json") as f:
return json.load(f)
def test_get_todos_contract(client):
"""GET /api/todos matches contract"""
contract = load_contract("get_todos")
response = client.get("/api/todos")
assert response.status_code == 200
jsonschema.validate(response.json(), contract["response"])
def test_create_todo_contract(client):
"""POST /api/todos matches contract"""
contract = load_contract("create_todo")
response = client.post("/api/todos", json={"title": "Test Todo"})
assert response.status_code == contract["response"]["status_code"]
jsonschema.validate(response.json(), contract["response"]["body"])
def test_create_todo_invalid_request(client):
"""Invalid request body"""
contract = load_contract("create_todo")
# Missing required field
response = client.post("/api/todos", json={})
assert response.status_code == 422 # Validation errorВопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.
Далее: CI/CD: Параллельный запуск и шардирование