Files
voidea/template/docs/05-testing.md
T

118 lines
3.7 KiB
Markdown

# Стандарты тестирования
## Философия
**Код без тестов — это не код, а предложение.** Если функцию нельзя проверить — она либо не нужна, либо её нужно переписать.
---
## Пирамида тестов
```
/\ 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'ов)