Files
mostovik-backend/tests
Aleksandr Meshchriakov c98ba76081
Some checks failed
CI/CD Pipeline / Code Quality Checks (pull_request) Failing after 2m39s
CI/CD Pipeline / Run Tests (pull_request) Successful in 3m0s
CI/CD Pipeline / Run API Inventory E2E Tests (pull_request) Successful in 35s
CI/CD Pipeline / Telegram Notify Success (pull_request) Has been skipped
feat(admin): expand exchange admin and unify admin UX
2026-03-24 13:58:24 +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          # Только тесты представлений

# Или напрямую через pytest
uv run pytest tests
uv run pytest tests/apps/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. Через pytest

```bash
# Все тесты
uv run pytest tests

# Конкретное приложение
uv run pytest tests/apps/user

# Конкретные группы тестов
uv run pytest tests -k test_models
uv run pytest tests -k test_views
uv run pytest tests -k test_serializers
uv run pytest tests -k test_services

# Или напрямую, если настроен PYTHONPATH
export PYTHONPATH=src:$PYTHONPATH
export DJANGO_SETTINGS_MODULE=settings.test
pytest tests/

🔧 Конфигурация

Настройки тестов

Тесты используют специальные настройки Django из src/settings/test.py:

  • База данных: SQLite в памяти для быстрого выполнения
  • Кэш: Local memory cache вместо Redis
  • Email: Локальный backend для тестирования
  • Celery: Синхронное выполнение задач
  • Миграции: Отключены для ускорения
  • Логирование: Отключено

Pytest конфигурация

Основные настройки в pytest.ini:

  • Автоматическое обнаружение Django настроек
  • Переиспользование тестовой базы данных
  • Отчеты о покрытии кода
  • Фильтрация предупреждений

Полезные опции pytest

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

# Запуск конкретного файла напрямую
uv run pytest tests/apps/user/test_models.py

# Все тесты с подробным выводом
uv run pytest tests -v

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

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

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

# Только юнит тесты
uv run pytest -m "unit"

# Исключить медленные тесты
uv run pytest -m "not slow"

# Тесты моделей
uv run pytest -m "models"

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

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

# Показать print statements
uv run pytest -s

# Подробные ошибки
uv run pytest --tb=long

# Показать локальные переменные при ошибке
uv run pytest --tb=long --showlocals

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

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

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

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

# HTML отчет
make test-cov

# Или напрямую
uv run pytest --cov=src --cov-report=html:htmlcov

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

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

uv run pytest --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. Ошибка импорта: Запускайте через uv run pytest ..., чтобы окружение и пути подхватывались корректно
  2. База данных: Убедитесь, что используются тестовые настройки
  3. Миграции: В тестах миграции отключены, но модели должны быть синхронизированы

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

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

# Пересоздание тестовой базы данных
rm -f test_db.sqlite3
uv run pytest --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. Читаемость: Тесты должны быть понятными и хорошо документированными