Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Фундамент: pytest-asyncio и окружение
async_testing_foundation

Фундамент: pytest-asyncio и окружение

Установка Docker, PostgreSQL, Redis — 30 минут. Настройка pytest-asyncio, event loop, первый async тест — 30 минут. Отдельное время на окружение!

Этот урок — критический фундамент всего курса. Мы потратим 60 минут (30 из них на установку!) чтобы настроить полноценное async-окружение для тестирования.

ВАЖНО: Без правильной настройки все следующие уроки будут бессмысленны. Не пропускайте этот урок.

Prerequisite Check

Перед началом убедитесь:

# test_async_knowledge.py import asyncio async def check_knowledge(): """Вы ДОЛЖНЫ понимать этот код""" tasks = [asyncio.sleep(0.1) for _ in range(5)] await asyncio.gather(*tasks) lock = asyncio.Lock() async with lock: print("Critical section") check_knowledge() # Если не понимаете — курс НЕ для вас!

Если этот код для вас непонятен — вернитесь к изучению async/await. Без этого фундамента курс будет потерей времени.

Установка окружения (30 минут)

Шаг 1: Docker (10 минут)

macOS:

# Установите Docker Desktop brew install --cask docker # Запустите Docker Desktop из Applications

Linux (Ubuntu):

curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo usermod -aG docker $USER # Перелогиньтесь!

Windows:

  • Скачайте Docker Desktop с docker.com
  • Включите WSL 2

Проверка:

docker --version # Docker version 24.0.0 или выше

Шаг 2: PostgreSQL (10 минут)

docker run -d \ --name pytest-postgres \ -e POSTGRES_PASSWORD=testpass \ -e POSTGRES_USER=postgres \ -e POSTGRES_DB=pytest_test \ -p 5432:5432 \ postgres:15-alpine # Проверка docker exec pytest-postgres pg_isready # /var/run/postgresql:5432 - accepting connections

Создаём тестовую схему:

docker exec -i pytest-postgres psql -U postgres -d pytest_test <<EOF CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, created_at TIMESTAMP DEFAULT NOW() ); EOF

Шаг 3: Redis (5 минут)

docker run -d \ --name pytest-redis \ -p 6379:6379 \ redis:7-alpine # Проверка docker exec pytest-redis redis-cli ping # PONG

Шаг 4: Python зависимости (5 минут)

# Создайте виртуальное окружение python3 -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate # Установите зависимости pip install pytest pytest-asyncio asyncpg redis[asyncio]

Проверка установки:

# test_deps.py import pytest import asyncpg import redis.asyncio as aioredis print("✅ All deps installed")
python test_deps.py # ✅ All deps installed

pytest-asyncio: первый тест (15 минут)

Настройка pytest.ini

# pytest.ini [pytest] asyncio_mode = auto

Что делает asyncio_mode = auto:

  • Автоматически обнаруживает async тесты
  • Управляет event loop за вас
  • Не нужно декорировать каждый тест

Первый async тест

# tests/test_first_async.py import pytest @pytest.mark.asyncio async def test_simple_async(): """Простейший async тест""" import asyncio await asyncio.sleep(0.001) assert True

Запускаем:

pytest tests/test_first_async.py -v

Ожидаемый результат:

test_simple_async PASSED

✅ Если тест прошел — pytest-asyncio работает!

Async фикстуры: базовый пример (15 минут)

Простая async фикстура

# conftest.py import pytest @pytest.fixture async def async_value(): """Async фикстура возвращает значение""" import asyncio await asyncio.sleep(0.001) # Имитация async операции return 42 @pytest.mark.asyncio async def test_async_fixture(async_value): """Тест использует async фикстуру""" assert async_value == 42

Фикстура с setup/teardown

# conftest.py import pytest @pytest.fixture async def async_resource(): """Async фикстура с teardown""" # Setup print("Opening async resource") resource = {"status": "open"} yield resource # Передаём в тест # Teardown print("Closing async resource") resource["status"] = "closed"

Тест:

@pytest.mark.asyncio async def test_resource(async_resource): assert async_resource["status"] == "open" # После теста выполнится teardown

Подключение к PostgreSQL (10 минут)

Async фикстура для PostgreSQL

# conftest.py import pytest import asyncpg @pytest.fixture async def db_connection(): """Async connection к PostgreSQL""" conn = await asyncpg.connect( host="localhost", port=5432, user="postgres", password="testpass", database="pytest_test" ) yield conn await conn.close()

Первый тест с БД

# tests/test_postgres.py import pytest @pytest.mark.asyncio async def test_postgres_connection(db_connection): """Проверяем что БД доступна""" result = await db_connection.fetchval("SELECT 1") assert result == 1 @pytest.mark.asyncio async def test_insert_user(db_connection): """Вставляем пользователя""" await db_connection.execute( "INSERT INTO users (email) VALUES ($1)", "test@example.com" ) count = await db_connection.fetchval("SELECT COUNT(*) FROM users") assert count > 0

Запускаем:

pytest tests/test_postgres.py -v

Проблема: Второй запуск упадет! Почему?

asyncpg.UniqueViolationError: duplicate key value

Причина: Данные остались в БД после первого теста.

Исправление (в следующем уроке): добавим транзакции с rollback.

Подключение к Redis (10 минут)

Async фикстура для Redis

# conftest.py import pytest import redis.asyncio as aioredis @pytest.fixture async def redis_client(): """Async Redis client""" client = aioredis.from_url( "redis://localhost:6379/15", # DB 15 для тестов decode_responses=True ) yield client await client.flushdb() # Чистим после теста await client.close()

Первый тест с Redis

# tests/test_redis.py import pytest @pytest.mark.asyncio async def test_redis_set_get(redis_client): """Set/Get в Redis""" await redis_client.set("key", "value") result = await redis_client.get("key") assert result == "value" @pytest.mark.asyncio async def test_redis_isolation(redis_client): """Проверяем изоляцию""" # Ключ из предыдущего теста не должен быть виден result = await redis_client.get("key") assert result is None # ✅ flushdb сработал

Типичные ошибки окружения

Ошибка #1: Забыли pytest.ini

# ❌ БЕЗ pytest.ini @pytest.mark.asyncio # Нужен декоратор! async def test(): pass
# ✅ С pytest.ini [pytest] asyncio_mode = auto # Декоратор не нужен для async def test_*

Ошибка #2: Неправильный asyncio_mode

# ❌ ПЛОХО asyncio_mode = strict # Старый режим # ✅ ХОРОШО asyncio_mode = auto # Современный

Ошибка #3: Docker контейнеры не запущены

# Проверка docker ps # Если контейнеров нет: docker start pytest-postgres pytest-redis

Ошибка #4: Порты заняты

# Проверка портов lsof -i :5432 # PostgreSQL lsof -i :6379 # Redis # Если порт занят, остановите процесс или измените порт docker run -p 5433:5432 postgres:15-alpine

Проверка финального окружения

# tests/test_environment.py import pytest import asyncpg import redis.asyncio as aioredis @pytest.mark.asyncio async def test_full_environment(): """Проверяем что всё работает""" # PostgreSQL pg_conn = await asyncpg.connect( "postgresql://postgres:testpass@localhost:5432/pytest_test" ) pg_result = await pg_conn.fetchval("SELECT 1") await pg_conn.close() assert pg_result == 1 # Redis redis = aioredis.from_url("redis://localhost:6379/15") await redis.set("test", "ok") redis_result = await redis.get("test") await redis.close() assert redis_result == "ok" print("✅ Environment ready!")

Запускаем:

pytest tests/test_environment.py -v -s

Ожидаемый результат:

test_full_environment PASSED
✅ Environment ready!

Что вы настроили

✅ Docker с PostgreSQL и Redis ✅ pytest-asyncio с auto mode ✅ asyncpg для async PostgreSQL ✅ redis[asyncio] для async Redis ✅ Базовые async фикстуры

Проверьте свои знания

Вопросы ещё не добавлены

Вопросы для этой подтемы ещё не добавлены.

Далее: Переход на async: async/await фикстуры