# Стандарты тестирования ## Философия **Код без тестов — это не код, а предложение.** Если функцию нельзя проверить — она либо не нужна, либо её нужно переписать. --- ## Пирамида тестов ``` /\ E2E (10%): сквозные сценарии / \ / \ /──────\ Integration (20%): API, БД, внешние сервисы / \ /──────────\ Unit (70%): изолированные модули / \ ``` --- ## Типы тестов ### Unit-тесты (`tests/unit/`) - Тестируют один класс/функцию в изоляции - Внешние зависимости мокаются - Быстрые (миллисекунды) - Пример: тест сервиса с mocked репозиторием ```python async def test_idea_service_create(): service = IdeaService(mock_db) idea = await service.create(user_id="1", title="Test", content="Content") assert idea.title == "Test" assert idea.status == "draft" ``` ### Integration-тесты (`tests/integration/`) - Тестируют взаимодействие компонентов - Используют реальную БД (SQLite в памяти) - Проверяют API endpoints, БД запросы - Пример: тест регистрации пользователя ```python async def test_register_user(async_client): response = await async_client.post("/api/v1/auth/register", json={ "username": "test", "email": "test@test.com", "password": "secret123", }) assert response.status_code == 201 data = response.json() assert "access_token" in data ``` ### Smoke-тесты (`tests/smoke/`) - Минимум 1 тест на каждый endpoint - Проверяют что endpoint отвечает и возвращает корректный статус - Быстрая проверка здоровья системы ```python async def test_health_endpoint(async_client): response = await async_client.get("/health") assert response.status_code == 200 assert response.json()["status"] == "healthy" ``` --- ## Покрытие - **Общее покрытие:** > 80% - **Критический код (auth, security, payments):** 100% - **Новый код:** без тестов не принимается в PR --- ## Что тестировать ### Обязательно (9 сценариев для каждого endpoint) 1. **Missing field** → 422 2. **Wrong type** → 422 3. **Expired/invalid token** → 401 4. **Wrong permissions** → 403 5. **Not found** → 404 6. **Conflict** → 409 7. **Success** → 200/201 8. **Rate limit** → 429 (если реализован) 9. **Idempotency** → тот же результат при повторе ### Для каждого сервиса - Успешное выполнение - Ошибка валидации - Ошибка БД - Граничные случаи (пустой список, null, максимальная длина) --- ## Конфигурация pytest ```ini # pyproject.toml или pytest.ini [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] python_files = ["test_*.py"] ``` --- ## [ASK] Вопросы по тестированию - Нужен ли coverage порог в CI? (рекомендуется 80%) - Использовать ли vcrpy для записи ответов внешних API? (да, для AI провайдеров) - Нужны ли performance-тесты? (да, для критических endpoint'ов)