dataloader/tests/conftest.py

106 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# tests/conftest.py
from __future__ import annotations
import asyncio
import sys
from typing import AsyncGenerator
from uuid import uuid4
import pytest
import pytest_asyncio
from dotenv import load_dotenv
from httpx import AsyncClient, ASGITransport
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker
load_dotenv()
from dataloader.api import app_main
from dataloader.config import APP_CONFIG
from dataloader.context import APP_CTX, get_session
from dataloader.storage.models import Base
from dataloader.storage.engine import create_engine, create_sessionmaker
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
pytestmark = pytest.mark.asyncio
@pytest_asyncio.fixture(scope="function")
async def db_engine() -> AsyncGenerator[AsyncEngine, None]:
"""
Создаёт тестовый движок для теста.
Использует реальную БД из конфига.
"""
engine = create_engine(APP_CONFIG.pg.url)
yield engine
await engine.dispose()
@pytest_asyncio.fixture(scope="function")
async def db_session(db_engine: AsyncEngine) -> AsyncGenerator[AsyncSession, None]:
"""
Предоставляет сессию БД для каждого теста.
НЕ использует транзакцию, чтобы работали advisory locks.
"""
sessionmaker = async_sessionmaker(bind=db_engine, expire_on_commit=False, class_=AsyncSession)
async with sessionmaker() as session:
yield session
await session.rollback()
@pytest_asyncio.fixture(scope="function")
async def clean_queue_tables(db_session: AsyncSession) -> None:
"""
Очищает таблицы очереди перед каждым тестом.
"""
schema = APP_CONFIG.pg.schema_queue
await db_session.execute(text(f"TRUNCATE TABLE {schema}.dl_job_events CASCADE"))
await db_session.execute(text(f"TRUNCATE TABLE {schema}.dl_jobs CASCADE"))
await db_session.commit()
@pytest_asyncio.fixture
async def client(db_session: AsyncSession) -> AsyncGenerator[AsyncClient, None]:
"""
HTTP клиент для тестирования API.
"""
async def override_get_session() -> AsyncGenerator[AsyncSession, None]:
yield db_session
app_main.dependency_overrides[get_session] = override_get_session
transport = ASGITransport(app=app_main)
async with AsyncClient(transport=transport, base_url="http://test") as c:
yield c
app_main.dependency_overrides.clear()
@pytest.fixture
def job_id() -> str:
"""
Генерирует уникальный job_id для тестов.
"""
return str(uuid4())
@pytest.fixture
def queue_name() -> str:
"""
Возвращает имя тестовой очереди.
"""
return "test.queue"
@pytest.fixture
def task_name() -> str:
"""
Возвращает имя тестовой задачи.
"""
return "test.task"