feat(core): add core module with mixins, services, and background jobs

- Add Model Mixins: TimestampMixin, SoftDeleteMixin, AuditMixin, etc.
- Add Base Services: BaseService, BulkOperationsMixin, QueryOptimizerMixin
- Add Base ViewSets with bulk operations
- Add BackgroundJob model for Celery task tracking
- Add BaseAppCommand for management commands
- Add permissions, pagination, filters, cache, logging
- Migrate tests to factory_boy + faker
- Add CHANGELOG.md
- 297 tests passing
This commit is contained in:
2026-01-21 11:47:26 +01:00
parent 06b30fca02
commit f121445313
72 changed files with 9258 additions and 594 deletions

368
tests/README.md Normal file
View File

@@ -0,0 +1,368 @@
# Тесты для mostovik-backend
Этот документ описывает организацию и запуск тестов в проекте mostovik-backend.
## 📁 Структура тестов
```
tests/
├── __init__.py # Корневой пакет тестов
├── conftest.py # Конфигурация pytest и общие фикстуры
├── README.md # Этот файл
└── apps/ # Тесты для Django приложений
├── __init__.py
└── user/ # Тесты для приложения user
├── __init__.py
├── factories.py # Фабрики для создания тестовых данных
├── test_models.py # Тесты моделей
├── test_serializers.py # Тесты сериализаторов
├── test_services.py # Тесты сервисного слоя
└── test_views.py # Тесты представлений (API views)
```
## 🚀 Запуск тестов
### Быстрый старт
```bash
# Запуск всех тестов (рекомендуемый способ)
make test
# Запуск конкретных тестов
make test TARGET=user # Все тесты user app
make test TARGET=models # Только тесты моделей
make test TARGET=views # Только тесты представлений
# Или напрямую через скрипт
python run_tests_simple.py
python run_tests_simple.py user
```
### Различные способы запуска
#### 1. Через универсальную команду make test (рекомендуется)
```bash
# Все тесты
make test
# Конкретные группы тестов
make test TARGET=user # Все тесты user app
make test TARGET=models # Тесты моделей
make test TARGET=views # Тесты представлений
make test TARGET=serializers # Тесты сериализаторов
make test TARGET=services # Тесты сервисов
# Можно также использовать полные имена
make test TARGET=test_models # То же что и models
make test TARGET=test_views # То же что и views
```
#### 2. Через улучшенный Django runner
```bash
# Все тесты
python run_tests_simple.py
# Конкретное приложение
python run_tests_simple.py user
# Конкретные группы тестов
python run_tests_simple.py models
python run_tests_simple.py views
python run_tests_simple.py serializers
python run_tests_simple.py services
# Полные имена файлов
python run_tests_simple.py test_models
python run_tests_simple.py test_views
```
#### 3. Через стандартный Django test runner
```bash
# Все тесты
python run_tests.py
# Конкретное приложение
python run_tests.py test tests.apps.user
# Конкретный класс тестов
python run_tests.py test tests.apps.user.test_models.UserModelTest
```
#### 4. Через pytest (возможны проблемы с pdbpp)
```bash
# Через скрипт-обертку
python run_pytest.py
# Или напрямую, если настроен PYTHONPATH
export PYTHONPATH=src:$PYTHONPATH
export DJANGO_SETTINGS_MODULE=config.settings.test
pytest tests/
```
## 🔧 Конфигурация
### Настройки тестов
Тесты используют специальные настройки Django из `src/config/settings/test.py`:
- **База данных**: SQLite в памяти для быстрого выполнения
- **Кэш**: Local memory cache вместо Redis
- **Email**: Локальный backend для тестирования
- **Celery**: Синхронное выполнение задач
- **Миграции**: Отключены для ускорения
- **Логирование**: Отключено
### Pytest конфигурация
Основные настройки в `pytest.ini`:
- Автоматическое обнаружение Django настроек
- Переиспользование тестовой базы данных
- Отчеты о покрытии кода
- Фильтрация предупреждений
### Полезные опции pytest
```bash
# Подробная информация (автоматически включена)
make test TARGET=models
# Запуск конкретного файла напрямую
python run_tests_simple.py test_models
# Все тесты с подробным выводом
python run_tests_simple.py
```
## 🏭 Фабрики тестовых данных
### UserFactory
```python
from tests.apps.user.factories import UserFactory
# Создание обычного пользователя
user = UserFactory.create_user()
# Создание пользователя с конкретными данными
user = UserFactory.create_user(
email="test@example.com",
username="testuser"
)
# Создание суперпользователя
admin = UserFactory.create_superuser()
```
### ProfileFactory
```python
from tests.apps.user.factories import ProfileFactory
# Создание профиля с новым пользователем
profile = ProfileFactory.create_profile()
# Создание профиля для существующего пользователя
profile = ProfileFactory.create_profile(
user=existing_user,
first_name="John",
last_name="Doe"
)
```
## 🧪 Фикстуры pytest
Доступные фикстуры в `tests/conftest.py`:
```python
def test_example(test_user, authenticated_api_client):
"""Пример использования фикстур"""
# test_user - готовый тестовый пользователь
# authenticated_api_client - API клиент с авторизацией
response = authenticated_api_client.get('/api/user/profile/')
assert response.status_code == 200
```
### Список фикстур
- `api_client` - DRF APIClient
- `user_factory` - Фабрика пользователей
- `profile_factory` - Фабрика профилей
- `test_user` - Готовый тестовый пользователь
- `test_superuser` - Готовый суперпользователь
- `test_profile` - Готовый профиль
- `authenticated_api_client` - Авторизованный API клиент
- `admin_api_client` - API клиент с админскими правами
## 📊 Маркеры тестов
Используйте маркеры для категоризации тестов:
```python
import pytest
@pytest.mark.unit
def test_user_model():
"""Юнит тест модели"""
pass
@pytest.mark.integration
def test_user_registration_flow():
"""Интеграционный тест"""
pass
@pytest.mark.slow
def test_heavy_operation():
"""Медленный тест"""
pass
```
Запуск по маркерам:
```bash
# Только юнит тесты
python run_pytest.py -m "unit"
# Исключить медленные тесты
python run_pytest.py -m "not slow"
# Тесты моделей
python run_pytest.py -m "models"
```
## 🔍 Отладка тестов
### Просмотр вывода
```bash
# Показать print statements
python run_pytest.py -s
# Подробные ошибки
python run_pytest.py --tb=long
# Показать локальные переменные при ошибке
python run_pytest.py --tb=long --showlocals
```
### Использование pdb
```python
def test_something():
import pdb; pdb.set_trace()
# ваш код тестирования
```
```bash
# Запуск с автоматическим pdb при ошибках
python run_pytest.py --pdb
```
## 📈 Покрытие кода
### Генерация отчета
```bash
# HTML отчет
make test-coverage
# Или напрямую
python run_pytest.py --cov=src --cov-report=html:htmlcov
# Открыть отчет в браузере
open htmlcov/index.html
```
### Просмотр в терминале
```bash
python run_pytest.py --cov=src --cov-report=term-missing
```
## 🔧 Добавление новых тестов
### Создание нового файла тестов
1. Создайте файл в соответствующей папке: `tests/apps/{app_name}/test_{module}.py`
2. Импортируйте необходимые зависимости
3. Создайте классы тестов, наследуя от `TestCase` или используя функции pytest
### Пример структуры теста
```python
"""Tests for new module"""
from django.test import TestCase
from tests.apps.user.factories import UserFactory
class NewModuleTest(TestCase):
"""Tests for NewModule"""
def setUp(self):
"""Подготовка данных для тестов"""
self.user = UserFactory.create_user()
def test_something(self):
"""Test description"""
# Arrange
expected_value = "test"
# Act
result = some_function()
# Assert
self.assertEqual(result, expected_value)
```
## 🚨 Решение проблем
### Частые ошибки
1. **Ошибка импорта**: Проверьте, что `PYTHONPATH` включает папку `src`
2. **База данных**: Убедитесь, что используются тестовые настройки
3. **Миграции**: В тестах миграции отключены, но модели должны быть синхронизированы
### Очистка тестовых данных
```bash
# Очистка кеша и временных файлов
make clean
# Пересоздание тестовой базы данных
rm -f test_db.sqlite3
python run_pytest.py --create-db
```
## 📚 Полезные ссылки
- [Django Testing Documentation](https://docs.djangoproject.com/en/3.2/topics/testing/)
- [Pytest Documentation](https://docs.pytest.org/)
- [pytest-django](https://pytest-django.readthedocs.io/)
- [DRF Testing](https://www.django-rest-framework.org/api-guide/testing/)
- [Factory Boy](https://factoryboy.readthedocs.io/)
## 🚀 Быстрая справка команд
```bash
# Главная команда - make test с опциональным TARGET
make test # Все тесты
make test TARGET=user # User app (77 тестов)
make test TARGET=models # Модели (16 тестов)
make test TARGET=views # Представления (20 тестов)
make test TARGET=serializers # Сериализаторы (22 теста)
make test TARGET=services # Сервисы (18 тестов)
```
## 🤝 Рекомендации
1. **Используйте make test** - это основная и самая удобная команда
2. **Именование**: Используйте описательные имена для тестов
3. **Изоляция**: Каждый тест должен быть независимым
4. **Покрытие**: Стремитесь к покрытию не менее 80%
5. **Быстрота**: Избегайте медленных операций в юнит тестах
6. **Читаемость**: Тесты должны быть понятными и хорошо документированными