Files
mostovik-backend/tests
Aleksandr Meshchriakov f121445313 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
2026-01-21 11:47:26 +01:00
..

Тесты для 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)

🚀 Запуск тестов

Быстрый старт

# Запуск всех тестов (рекомендуемый способ)
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 (рекомендуется)

# Все тесты
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

# Все тесты
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

# Все тесты
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)

# Через скрипт-обертку
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

# Подробная информация (автоматически включена)
make test TARGET=models

# Запуск конкретного файла напрямую
python run_tests_simple.py test_models

# Все тесты с подробным выводом
python run_tests_simple.py

🏭 Фабрики тестовых данных

UserFactory

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

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:

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 клиент с админскими правами

📊 Маркеры тестов

Используйте маркеры для категоризации тестов:

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

Запуск по маркерам:

# Только юнит тесты
python run_pytest.py -m "unit"

# Исключить медленные тесты
python run_pytest.py -m "not slow"

# Тесты моделей
python run_pytest.py -m "models"

🔍 Отладка тестов

Просмотр вывода

# Показать print statements
python run_pytest.py -s

# Подробные ошибки
python run_pytest.py --tb=long

# Показать локальные переменные при ошибке
python run_pytest.py --tb=long --showlocals

Использование pdb

def test_something():
    import pdb; pdb.set_trace()
    # ваш код тестирования
# Запуск с автоматическим pdb при ошибках
python run_pytest.py --pdb

📈 Покрытие кода

Генерация отчета

# HTML отчет
make test-coverage

# Или напрямую
python run_pytest.py --cov=src --cov-report=html:htmlcov

# Открыть отчет в браузере
open htmlcov/index.html

Просмотр в терминале

python run_pytest.py --cov=src --cov-report=term-missing

🔧 Добавление новых тестов

Создание нового файла тестов

  1. Создайте файл в соответствующей папке: tests/apps/{app_name}/test_{module}.py
  2. Импортируйте необходимые зависимости
  3. Создайте классы тестов, наследуя от TestCase или используя функции pytest

Пример структуры теста

"""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. Миграции: В тестах миграции отключены, но модели должны быть синхронизированы

Очистка тестовых данных

# Очистка кеша и временных файлов
make clean

# Пересоздание тестовой базы данных
rm -f test_db.sqlite3
python run_pytest.py --create-db

📚 Полезные ссылки

🚀 Быстрая справка команд

# Главная команда - 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. Читаемость: Тесты должны быть понятными и хорошо документированными