test: use PostgreSQL and live model integrations

This commit is contained in:
2026-09-25 20:30:28 +08:00
parent dd48e13cf2
commit 8bebcdb470
9 changed files with 144 additions and 77 deletions
+46 -10
View File
@@ -1,13 +1,28 @@
import os
from pathlib import Path
from uuid import uuid4
import pytest
from alembic import command
from alembic.config import Config
from sqlalchemy import create_engine
from sqlalchemy.engine import make_url
from sqlalchemy.orm import sessionmaker
from wisegrade.config import get_settings
from wisegrade.db import Base, engine_for
from wisegrade.db import engine_for
from wisegrade.seed import seed_initial
from wisegrade import models # noqa: F401
@pytest.fixture(scope="session")
def test_database_url():
value = os.environ.get("TEST_DATABASE_URL")
if not value:
pytest.fail("Set TEST_DATABASE_URL to a dedicated PostgreSQL database named wisegrade_tests")
url = make_url(value)
if url.drivername != "postgresql+psycopg" or url.database != "wisegrade_tests":
pytest.fail("TEST_DATABASE_URL must use postgresql+psycopg and the wisegrade_tests database")
return url
@pytest.fixture
@@ -24,14 +39,35 @@ def environment(tmp_path, monkeypatch):
@pytest.fixture
def session_factory(environment):
engine = engine_for(f"sqlite:///{environment / 'test.db'}")
Base.metadata.create_all(engine)
factory = sessionmaker(bind=engine, expire_on_commit=False)
with factory() as db:
seed_initial(db)
yield factory
engine.dispose()
def session_factory(environment, monkeypatch, test_database_url):
admin_engine = create_engine(test_database_url, isolation_level="AUTOCOMMIT")
name = f"wisegrade_test_{uuid4().hex}"
engine = None
created = False
try:
with admin_engine.connect() as connection:
connection.exec_driver_sql(f'CREATE DATABASE "{name}"')
created = True
url = test_database_url.set(database=name).render_as_string(hide_password=False)
monkeypatch.setenv("DATABASE_URL", url)
get_settings.cache_clear()
backend_root = Path(__file__).resolve().parents[1]
migration_config = Config(str(backend_root / "alembic.ini"))
migration_config.set_main_option("script_location", str(backend_root / "migrations"))
command.upgrade(migration_config, "head")
engine = engine_for(url)
factory = sessionmaker(bind=engine, expire_on_commit=False)
with factory() as db:
seed_initial(db)
yield factory
finally:
if engine is not None:
engine.dispose()
get_settings.cache_clear()
if created:
with admin_engine.connect() as connection:
connection.exec_driver_sql(f'DROP DATABASE "{name}" WITH (FORCE)')
admin_engine.dispose()
@pytest.fixture