Полнофункциональное веб-приложение с REST API, веб-интерфейсом, PostgreSQL и автотестами.
graph LR
Client[Клиент] --> API[FastAPI API]
API --> Pydantic[Pydantic валидация]
Pydantic --> DB[(PostgreSQL)]
Tests[Автотесты] --> FluentAPI[Fluent API клиент]
FluentAPI --> API
API --> Response[JSON ответ]
Response --> ExplicitValidation[Явная валидация в тестах]
%% Обратный поток тоже через Pydantic
DB --> Pydantic
Pydantic --> API
subgraph "Серверная валидация"
Pydantic
DB
style Pydantic fill:#e1f5fe
style DB fill:#e1f5fe
end
subgraph "Клиентская валидация"
ExplicitValidation
style ExplicitValidation fill:#f3e5f5
end
Тип | Библиотека | Назначение | Пример |
---|---|---|---|
Серверная | Pydantic | Валидирует входящие/исходящие данные API | class UserCreate(SQLModel): name: str |
Клиентская | Voluptuous | Явная проверка структуры ответов в тестах | response.validate_users_list() |
Было (verbose):
response = requests.post("/api/users", json={"name": "John", "job": "Dev"})
assert response.status_code == 201
data = response.json()
assert "id" in data
assert "name" in data
# + еще 'N' строк проверок...
Стало (fluent с явной валидацией):
response = api.users().create("John", "Dev").validate_user_created()
user_id = int(response.extract("id"))
# Пользователи
response.validate_users_list() # Список пользователей
response.validate_single_user() # Один пользователь
response.validate_user_created() # Созданный пользователь
response.validate_user_updated() # Обновленный пользователь
# Ресурсы
response.validate_resources_list() # Список ресурсов
response.validate_single_resource() # Один ресурс
response.validate_resource_created()# Созданный ресурс
response.validate_resource_updated()# Обновленный ресурс
# Аутентификация
response.validate_register_success()# Успешная регистрация
response.validate_login_success() # Успешный логин
# Система и ошибки
response.validate_system_health() # Статус системы
response.validate_api_error() # Ошибки API
# Для тестирования не-JSON ответов или edge cases
response = api.users().get_raw(999999) # Без автоматических проверок
assert response.status_code == 404
response.validate_api_error() # Явная валидация только если нужно
# Тестирование HTML ошибок
response = api_client.get("/broken-endpoint")
assert "text/html" in response.headers.get("content-type", "")
# Никакой JSON валидации не требуется
- Видимость - каждый шаг валидации явно виден в тесте
- Гибкость - можно пропустить валидацию для edge cases
- Диагностика - понятные ошибки с контекстом в Allure отчетах
- Разделение ответственности - клиент делает HTTP, тесты валидируют
- Веб-интерфейс - современный Bootstrap UI
- PostgreSQL интеграция - пользователи хранятся в базе данных
- Docker Compose - полная инфраструктура (API + PostgreSQL + Adminer)
- Автоматическая миграция - создание таблиц и загрузка данных при старте
- Расширенный healthcheck - подробная информация о состоянии системы
- CRUD тесты с реальной БД - изолированное тестирование операций
- SQLModel ORM - современный подход к работе с базой данных
- Пагинация - эффективная обработка больших наборов данных
- Подробное логирование - логи всех операций
- cURL Integration - автоматическая генерация curl команд для отладки ошибок
- Allure отчеты - детальная отчетность с автодеплоем
- Явная валидация схем - видимые шаги валидации в тестах
- Fluent API - тесты с method chaining и явной валидацией
- Edge case поддержка - тестирование не-JSON ответов через raw методы
- Convenience методы - удобная валидация через .validate_*()
- Environment Management - тесты на local/staging/prod
# Клонировать репозиторий
git clone <repo-url>
cd python_advanced
# Запустить всю инфраструктуру
docker-compose up --build
# Доступные сервисы:
# 🌐 Веб-интерфейс: http://localhost:8000/ui
# 📖 API Docs: http://localhost:8000/docs
# ❤️ Health Check: http://localhost:8000/status
# 🛠️ Adminer (БД): http://localhost:8080
Что включено в Docker Compose:
- FastAPI app - основное приложение на порту 8000
- PostgreSQL 15 - база данных на порту 5432
- Adminer - веб-интерфейс для управления БД на порту 8080
# Установка Poetry (если еще не установлен)
curl -sSL https://install.python-poetry.org | python3 -
# Установка зависимостей проекта
poetry install
# Настройка переменных окружения
cp .env.example .env
# Отредактируйте .env файл
# Запуск только БД
docker-compose up db -d
# Запуск приложения
poetry run python app/main.py
Создайте .env
файл в корне проекта:
Переменная | Описание | Значение по умолчанию | Обязательно |
---|---|---|---|
POSTGRES_USER | Пользователь PostgreSQL | postgres | Да |
POSTGRES_PASSWORD | Пароль PostgreSQL | example | Да |
POSTGRES_HOST | Хост PostgreSQL | localhost | Да |
POSTGRES_PORT | Порт PostgreSQL | 5432 | Да |
POSTGRES_DB | База данных PostgreSQL | postgres | Да |
DATABASE_ENGINE | Строка подключения (автогенерируется) | - | Да |
DATABASE_POOL_SIZE | Размер пула соединений | 10 | Нет |
HOST | IP адрес для запуска сервера | 0.0.0.0 | Нет |
PORT | Порт для запуска сервера | 8000 | Нет |
API_URL | Базовый URL для тестов | http://localhost:8000 | Да |
APP_VERSION | Версия приложения | 1.0.0 | Нет |
LOG_LEVEL | Уровень логирования | DEBUG | Нет |
SHOW_DB_LOGS | Показывать SQL логи | true | Нет |
Пример .env
:
# DB
POSTGRES_USER=postgres
POSTGRES_PASSWORD=example
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=postgres
# DATABASE_ENGINE
DATABASE_ENGINE=postgresql+psycopg2://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
# Other settings
DATABASE_POOL_SIZE=10
HOST=0.0.0.0
PORT=8000
API_URL=http://localhost:8000
APP_VERSION=1.0.0
LOG_LEVEL=DEBUG
SHOW_DB_LOGS=true
# Запустить PostgreSQL (через Docker)
docker-compose up db -d
# Запустить приложение
poetry run python app/main.py
# Сервер: http://localhost:8000
# Все тесты с Allure отчетом (убедитесь что сервер запущен)
poetry run pytest tests/ -v --alluredir=allure-results
# Тесты с явной валидацией схем
pytest tests/test_api_schemas.py -v
# Разные окружения
pytest tests/ --env=local # http://localhost:8000
pytest tests/ --env=staging # https://staging-api.com
pytest tests/ --env=prod # https://api.com
# По маркерам
poetry run pytest -m smoke --alluredir=allure-results # Smoke тесты
poetry run pytest -m auth --alluredir=allure-results # Аутентификация
poetry run pytest -m crud --alluredir=allure-results # CRUD операции
poetry run pytest -m pagination --alluredir=allure-results # Пагинация
poetry run pytest -m "not slow" --alluredir=allure-results # Исключить медленные (delay)
pytest -m schema # Валидация схем
# Конкретный файл
poetry run pytest tests/test_auth.py -v --alluredir=allure-results
# Генерация Allure отчета
poetry run allure serve allure-results
# Статический Allure отчет
poetry run allure generate allure-results --output allure-report --clean
Через Docker (Adminer):
- URL: http://localhost:8080
- Система: PostgreSQL
- Сервер: db
- Пользователь: postgres
- Пароль: example
- База данных: postgres
Через CLI:
# Подключение к контейнеру PostgreSQL
docker exec -it fastapi_postgres psql -U postgres -d postgres
# Или через локальный клиент
psql -h localhost -U postgres -d postgres
При первом запуске приложение автоматически:
- Создает таблицы в PostgreSQL (User, Resource)
- Загружает 12 тестовых пользователей из
app/data/users.json
в БД - Загружает 12 тестовых ресурсов из
app/data/resources.json
в БД
Сервер автоматически генерирует интерактивную документацию:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
Система:
GET /status
- Подробный статус приложения с информацией о БД
Пользователи:
GET /api/users
- Список пользователей (с пагинацией и delay)GET /api/users/{id}
- Получить пользователя по IDPOST /api/users
- Создать пользователя (сохраняется в БД)PUT /api/users/{id}
- Полное обновление пользователяPATCH /api/users/{id}
- Частичное обновление пользователяDELETE /api/users/{id}
- Удалить пользователя (из БД)
Аутентификация:
POST /api/register
- Регистрация (с валидацией email)POST /api/login
- Вход в систему
Ресурсы:
GET /api/resources
- Список ресурсов (из JSON файла)GET /api/resources/{id}
- Получить ресурс по IDPOST /api/resources
- Создать ресурс (сохраняется в БД)PUT /api/resources/{id}
- Полное обновление ресурсаPATCH /api/resources/{id}
- Частичное обновление ресурсаDELETE /api/resources/{id}
- Удалить ресурс (из БД)
├── app/
│ ├── data/
│ │ ├── users.json # Тестовые данные пользователей (seed)
│ │ └── resources.json # Тестовые данные ресурсов
│ │
│ ├── database/
│ │ ├── engine.py # Настройка SQLModel и PostgreSQL
│ │ └── seed.py # Загрузка seed данных в БД
│ │
│ ├── routes/
│ │ ├── __init__.py
│ │ ├── auth.py # Эндпоинты аутентификации
│ │ ├── resources.py # Эндпоинты ресурсов (прямая работа с БД)
│ │ ├── system.py # Системные эндпоинты (healthcheck)
│ │ ├── users.py # Эндпоинты пользователей (прямая работа с БД)
│ │ └── ui.py # Веб-интерфейс
│ │
│ ├── main.py # FastAPI приложение и настройка
│ ├── exceptions.py # Унифицированные исключения
│ └── models.py # SQLModel модели для БД и API
│
├── tests/
| ├── schemas.py # Схемы валидации API (Voluptuous)
| ├── api_client.py # Fluent API клиент с явной валидацией
| ├── test_api_schemas.py # Тесты с явной валидацией схем
│ ├── test_auth.py # Тесты аутентификации (email валидация)
│ ├── test_crud_users.py # CRUD операции с users
│ ├── test_crud_resources.py # CRUD операции с resources
│ ├── test_resources.py # Тесты ресурсов
│ ├── test_smoke.py # Smoke тесты
│ ├── test_special.py # Специальные тесты (delayed response)
│ ├── test_users.py # Тесты пользователей
│ ├── test_pagination.py # Тесты пагинации
│ ├── test_validation.py # Валидация
│ ├── test_demo_statuses.py # Демонстрация статусов тестов (pass/fail/skip/xfail/xpass)
│ ├── conftest.py # Поддержка различных окружений, Pytest фикстуры и Allure конфигурация
│ └── assertions.py # Хелперы для проверок с Allure отчетностью
│
├── allure-results/ # Результаты тестов для Allure (генерируется)
├── allure-report/ # Статический Allure отчет (генерируется)
├── docker-compose.yml # Docker инфраструктура с переменными окружения
├── Dockerfile # Образ FastAPI приложения
├── .dockerignore # Docker ignore файл
├── pyproject.toml # Poetry конфигурация и зависимости
├── poetry.lock # Закрепленные версии зависимостей
├── .env # Переменные окружения (PostgreSQL + настройки)
├── .gitignore # Git ignore файл
├── api.log # Логи API (генерируется автоматически)
└── README.md # Документация проекта
Всего: 104 теста (включая тесты с параметризацией) разбитых по функциональным областям.
- Smoke - доступность сервиса, статус приложения
- Authentication - регистрация/логин с email валидацией
- CRUD operations - создание/обновление/удаление пользователей и ресурсов в БД
- Users - получение, пагинация, уникальность ID
- Resources - получение, пагинация ресурсов (из JSON)
- Special - delayed response с измерением времени
- Pagination - проверка расчетов pages/items, различных данных на страницах, невалидные параметры
- Schema Validation - явная проверка структуры API ответов с convenience методами
- Business Rules - консистентность данных
- Demo Statuses - демонстрация всех статусов pytest (pass/fail/skip/xfail/xpass)
- Изоляция тестов - каждый тест работает независимо
- Реальная БД - CRUD тесты создают/удаляют записи в PostgreSQL
- Автоматическая проверка доступности сервиса перед запуском
- Параметризованные тесты для покрытия различных сценариев
- Подробные логи всех операций для отладки
- Allure отчеты - детальная отчетность с категоризацией и вложениями
- cURL команды - автоматическое логирование для отладки ошибок
- Явная валидация схем - каждый шаг валидации видим в тестах
- Convenience методы - удобные .validate_*() для популярных схем
- Edge case гибкость - возможность тестировать некорректные ответы
- Business logic helpers - отдельные проверки бизнес-логики после валидации схем
Проект интегрирован с Allure Framework для генерации подробных тест-отчетов:
# Установка Allure (macOS)
brew install allure
# Установка Allure (Windows)
scoop install allure
# Запуск тестов с генерацией данных для Allure
poetry run pytest tests/ --alluredir=allure-results
# Открытие интерактивного отчета
poetry run allure serve allure-results
# Генерация статического отчета
poetry run allure generate allure-results --output allure-report --clean
# Перезапуск только приложения (без БД)
docker-compose up app --build
# Просмотр логов
docker-compose logs app
docker-compose logs db
# Остановка всех сервисов
docker-compose down
# Очистка данных БД
docker-compose down -v
# Форматирование кода
poetry run black app/ tests/
# Линтинг
poetry run pylint app/
# Тесты с явной валидацией Fluent API
poetry run pytest tests/test_api_schemas.py --env=local
# Просмотр зависимостей
poetry show --tree
# Allure отчеты
poetry run pytest tests/ --alluredir=allure-results
poetry run allure serve allure-results
# Проверка статуса приложения
curl http://localhost:8000/status
# Проверка здоровья PostgreSQL
docker-compose exec db pg_isready -U postgres
# Просмотр статистики Docker
docker stats
- Модульная архитектура - роуты разделены по функциональным областям
- SQLModel интеграция - современный ORM от создателя FastAPI
- Connection pooling - эффективное управление соединениями с БД
- Автоматические миграции - создание таблиц при старте приложения
- Автозагрузка данных - seed данные загружаются при первом запуске
- Email валидация с использованием
email-validator
- Delayed response для тестирования с задержкой
- Health check с проверкой состояния БД
- Унифицированная обработка ошибок - консистентные API исключения
- Типизация - полная поддержка type hints
- Docker - контейнеризация
- Adminer интеграция - веб-интерфейс для управления БД
- Allure отчеты - детальная отчетность с автодеплоем
- Явная архитектура валидации - прозрачные и гибкие тесты
- Профессиональные принципы тестирования - разделение ответственности, видимость шагов
База данных недоступна:
# Проверить статус контейнеров
docker-compose ps
# Перезапустить БД
docker-compose restart db
# Проверить логи БД
docker-compose logs db
Ошибки в тестах:
# Убедиться что сервер запущен
curl http://localhost:8000/status
# Проверить переменные окружения
cat .env
# Запустить конкретный тест с подробными логами
poetry run pytest tests/test_smoke.py::TestSmoke::test_service_is_alive -v -s
Проблемы с зависимостями:
# Переустановить зависимости
poetry install --no-cache
# Обновить lock файл
poetry lock --no-update