🧪 Тесты для AnonBot
📁 Структура тестов
tests/
├── __init__.py
├── conftest.py # Конфигурация pytest
├── requirements.txt # Тестовые зависимости
├── README.md # Документация тестов
├── unit/ # Unit тесты
│ ├── __init__.py
│ ├── models/ # Тесты моделей данных
│ │ ├── __init__.py
│ │ ├── test_user.py
│ │ ├── test_question.py
│ │ ├── test_user_block.py
│ │ └── test_user_settings.py
│ ├── services/ # Тесты сервисов
│ │ ├── __init__.py
│ │ ├── validation/ # Тесты валидации
│ │ │ ├── __init__.py
│ │ │ ├── test_input_validator.py
│ │ │ └── test_validation_middleware.py
│ │ ├── auth/ # Тесты авторизации
│ │ │ ├── __init__.py
│ │ │ ├── test_auth_service.py
│ │ │ └── test_permissions.py
│ │ ├── business/ # Тесты бизнес-сервисов
│ │ │ ├── __init__.py
│ │ │ ├── test_user_service.py
│ │ │ ├── test_question_service.py
│ │ │ ├── test_message_service.py
│ │ │ └── test_pagination_service.py
│ │ ├── infrastructure/ # Тесты инфраструктурных сервисов
│ │ │ ├── __init__.py
│ │ │ ├── test_database.py
│ │ │ └── test_metrics.py
│ │ └── test_utils.py # Тесты утилит
│ ├── database/ # Тесты CRUD операций
│ │ ├── __init__.py
│ │ └── test_crud.py
│ ├── handlers/ # Тесты обработчиков
│ │ ├── __init__.py
│ │ ├── test_start.py
│ │ ├── test_questions.py
│ │ ├── test_answers.py
│ │ └── test_admin.py
│ ├── middlewares/ # Тесты middleware
│ │ ├── __init__.py
│ │ ├── test_validation_middleware.py
│ │ └── test_rate_limit_middleware.py
│ └── config/ # Тесты конфигурации
│ ├── __init__.py
│ ├── test_config.py
│ └── test_constants.py
└── integration/ # Интеграционные тесты
├── __init__.py
├── test_database_integration.py
└── test_bot_integration.py
🚀 Запуск тестов
Установка зависимостей
pip install -r tests/requirements.txt
Запуск всех тестов
pytest
Запуск unit тестов
pytest tests/unit/
Запуск интеграционных тестов
pytest tests/integration/
Запуск тестов с покрытием
pytest --cov=. --cov-report=html
Запуск тестов по категориям
# Тесты моделей
pytest -m models
# Тесты сервисов
pytest -m services
# Тесты БД
pytest -m database
# Тесты авторизации
pytest -m auth
# Тесты валидации
pytest -m validation
📊 Покрытие кода
Цель покрытия: 80%+
Приоритеты покрытия:
-
Критически важные компоненты (90%+):
- Модели данных
- Валидация
- Авторизация
- CRUD операции
- Бизнес-сервисы
-
Важные компоненты (80%+):
- Обработчики
- Middleware
- Инфраструктурные сервисы
-
Дополнительные компоненты (70%+):
- Утилиты
- Конфигурация
- Интеграционные тесты
🎯 Что тестировать
Модели данных
- Создание объектов
- Валидация полей
- Методы форматирования
- HTML экранирование
- Сериализация/десериализация
Валидация
- Валидация Telegram ID
- Валидация текстового контента
- Валидация deep links
- Валидация callback data
- HTML санитизация
- Спам-фильтры
Авторизация
- Проверка ролей
- Система разрешений
- Проверка прав доступа
- Обработка ошибок
CRUD операции
- Создание, чтение, обновление, удаление
- Batch операции
- Cursor-based пагинация
- Обработка ошибок БД
- Транзакции
Бизнес-сервисы
- Создание/обновление пользователей
- Обработка вопросов и ответов
- Форматирование сообщений
- Пагинация
- Интеграция с БД
Обработчики
- Обработка команд
- Deep linking
- FSM состояния
- Callback обработчики
- Валидация входных данных
Middleware
- Валидация входящих данных
- Rate limiting
- Обработка ошибок
- Пропуск событий
🔧 Настройка тестов
Переменные окружения
Создайте .env.test файл:
# Тестовая конфигурация
TELEGRAM_BOT_TOKEN=test_token
DATABASE_PATH=:memory:
ADMINS=123456789,987654321
LOG_LEVEL=DEBUG
METRICS_PORT=9090
Фикстуры
Основные фикстуры в conftest.py:
mock_database- мок для DatabaseServicemock_auth- мок для AuthServicemock_validator- мок для InputValidatormock_utils- мок для UtilsServicemock_config- мок для конфигурации
📝 Примеры тестов
Unit тест
def test_user_creation_basic():
"""Тест базового создания пользователя"""
user = User(
telegram_id=123456789,
first_name="Test",
chat_id=123456789,
profile_link="test_link"
)
assert user.telegram_id == 123456789
assert user.first_name == "Test"
assert user.is_active is True
assert user.is_superuser is False
Async тест
@pytest.mark.asyncio
async def test_create_user_async():
"""Тест асинхронного создания пользователя"""
user_service = UserService(mock_database)
user = await user_service.create_or_update_user(telegram_user, chat_id)
assert user.telegram_id == telegram_user.id
assert user.first_name == telegram_user.first_name
Тест с моками
def test_auth_service_is_admin(mock_config):
"""Тест проверки администратора"""
auth_service = AuthService(mock_database, mock_config)
assert auth_service.is_admin(123456789) is True
assert auth_service.is_admin(999999999) is False
🚨 Обработка ошибок
Все тесты должны:
- Проверять как успешные, так и ошибочные сценарии
- Использовать соответствующие исключения
- Проверять логирование ошибок
- Тестировать восстановление после ошибок
📈 Производительность
Тесты должны:
- Выполняться быстро (< 1 секунды для unit тестов)
- Использовать моки для внешних зависимостей
- Тестировать производительность критических компонентов
- Включать benchmark тесты для БД операций
🔍 Отладка
Для отладки тестов:
# Запуск с подробным выводом
pytest -v -s
# Запуск конкретного теста
pytest tests/unit/models/test_user.py::TestUser::test_user_creation_basic
# Запуск с остановкой на первой ошибке
pytest -x
# Запуск с отладочным выводом
pytest --pdb