3ccd94f661
Test Organization: - Create tests/unit/, tests/integration/, tests/system/ directories - Move existing tests into appropriate categories - Add pytest markers (@pytest.mark.unit, @pytest.mark.integration) Shared Fixtures: - Create conftest.py with SQLite engine (for unit tests) - Add PostgreSQL session fixture with transaction rollback - Add TestClient fixture for API tests Configuration: - Update pyproject.toml with asyncio_mode=auto - Add test markers and default addopts - Add aiosqlite dependency for SQLite support E2E Testing: - Initialize Playwright in e2e/ directory - Add playwright.config.ts - Create login flow E2E test Build: - Add test-unit, test-integration, test-system, test-e2e to Makefile - Update test target to run all categories - Add testing documentation to README Note: Some tests have import issues due to missing python-jose package in dev environment. This needs to be addressed separately.
93 lines
2.5 KiB
Python
93 lines
2.5 KiB
Python
"""Shared test fixtures for all test categories."""
|
|
|
|
import asyncio
|
|
import os
|
|
from typing import AsyncGenerator, Generator
|
|
|
|
import pytest
|
|
import pytest_asyncio
|
|
from fastapi.testclient import TestClient
|
|
from sqlalchemy import create_engine, text
|
|
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
from src.config import Settings, build_database_url
|
|
from src.models.base import Base
|
|
from src.main import app
|
|
|
|
|
|
# Unit test fixtures (SQLite in-memory)
|
|
|
|
@pytest.fixture(scope="session")
|
|
def sqlite_engine():
|
|
"""Create a SQLite in-memory engine for unit tests."""
|
|
engine = create_engine("sqlite:///:memory:", connect_args={"check_same_thread": False})
|
|
Base.metadata.create_all(engine)
|
|
yield engine
|
|
engine.dispose()
|
|
|
|
|
|
@pytest.fixture
|
|
def sqlite_session(sqlite_engine) -> Generator:
|
|
"""Provide a SQLite session for unit tests."""
|
|
connection = sqlite_engine.connect()
|
|
transaction = connection.begin()
|
|
session = sessionmaker(bind=connection)()
|
|
|
|
yield session
|
|
|
|
session.close()
|
|
transaction.rollback()
|
|
connection.close()
|
|
|
|
|
|
# Integration test fixtures (PostgreSQL)
|
|
|
|
TEST_DATABASE_URL = build_database_url(
|
|
user="headquarter",
|
|
password="headquarter",
|
|
host="localhost",
|
|
port=5432,
|
|
database="headquarter",
|
|
)
|
|
|
|
|
|
@pytest_asyncio.fixture(scope="session")
|
|
async def postgres_engine():
|
|
"""Create a PostgreSQL engine for integration tests."""
|
|
engine = create_async_engine(TEST_DATABASE_URL)
|
|
async with engine.begin() as conn:
|
|
await conn.run_sync(Base.metadata.create_all)
|
|
yield engine
|
|
await engine.dispose()
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def db_session(postgres_engine) -> AsyncGenerator[AsyncSession, None]:
|
|
"""Provide a database session with transaction rollback."""
|
|
async with postgres_engine.connect() as connection:
|
|
transaction = await connection.begin_nested()
|
|
session_factory = async_sessionmaker(
|
|
connection, expire_on_commit=False, class_=AsyncSession
|
|
)
|
|
session = session_factory()
|
|
|
|
yield session
|
|
|
|
await session.close()
|
|
await transaction.rollback()
|
|
|
|
|
|
@pytest.fixture
|
|
def test_client() -> Generator[TestClient, None, None]:
|
|
"""Provide a FastAPI test client."""
|
|
with TestClient(app) as client:
|
|
yield client
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def configure_test_env(monkeypatch):
|
|
"""Configure environment for testing."""
|
|
monkeypatch.setenv("DATABASE_URL", TEST_DATABASE_URL)
|
|
monkeypatch.setenv("APP_ENV", "testing")
|