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