Praneeth Yerrapragada commited on
Commit
312b13f
1 Parent(s): a4ec216

test: setup pytests

Browse files
Files changed (4) hide show
  1. .env.example +2 -2
  2. config/index.py +2 -0
  3. tests/conftest.py +86 -0
  4. tests/pytest.ini +2 -0
.env.example CHANGED
@@ -47,7 +47,7 @@ APP_PORT=8000
47
  # Postgres database configuration
48
  POSTGRES_USER=postgres
49
  POSTGRES_PASSWORD=postgres
50
- POSTGRES_DB_NAME=codepath_project_postgres_local
51
  POSTGRES_DB_HOST=localhost
52
  POSTGRES_DB_PORT=5432
53
- SQLALCHEMY_DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_DB_HOST}:${POSTGRES_DB_PORT}/${POSTGRES_DB_NAME}
 
47
  # Postgres database configuration
48
  POSTGRES_USER=postgres
49
  POSTGRES_PASSWORD=postgres
50
+ POSTGRES_DB_NAME=postgres
51
  POSTGRES_DB_HOST=localhost
52
  POSTGRES_DB_PORT=5432
53
+ SQLALCHEMY_DATABASE_URL=postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_DB_HOST}:${POSTGRES_DB_PORT}/${POSTGRES_DB_NAME}
config/index.py CHANGED
@@ -26,9 +26,11 @@ class Config:
26
  POSTGRES_USER = os.getenv("POSTGRES_USER")
27
  POSTGRES_PASSWORD = os.getenv("POSTGRES_PASSWORD")
28
  POSTGRES_DB_NAME = os.getenv("POSTGRES_DB_NAME")
 
29
  POSTGRES_DB_HOST = os.getenv("POSTGRES_DB_HOST")
30
  POSTGRES_DB_PORT = os.getenv("POSTGRES_DB_PORT")
31
  SQLALCHEMY_DATABASE_URL = f"postgresql+asyncpg://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_DB_HOST}:{POSTGRES_DB_PORT}/{POSTGRES_DB_NAME}"
 
32
 
33
 
34
  config = Config
 
26
  POSTGRES_USER = os.getenv("POSTGRES_USER")
27
  POSTGRES_PASSWORD = os.getenv("POSTGRES_PASSWORD")
28
  POSTGRES_DB_NAME = os.getenv("POSTGRES_DB_NAME")
29
+ POSTGRES_TEST_DB_NAME = os.getenv("POSTGRES_TEST_DB_NAME")
30
  POSTGRES_DB_HOST = os.getenv("POSTGRES_DB_HOST")
31
  POSTGRES_DB_PORT = os.getenv("POSTGRES_DB_PORT")
32
  SQLALCHEMY_DATABASE_URL = f"postgresql+asyncpg://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_DB_HOST}:{POSTGRES_DB_PORT}/{POSTGRES_DB_NAME}"
33
+ SQLALCHEMY_TEST_DATABASE_URL = f"postgresql+asyncpg://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_DB_HOST}:{POSTGRES_DB_PORT}/{POSTGRES_TEST_DB_NAME}"
34
 
35
 
36
  config = Config
tests/conftest.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Credits: https://github.com/ThomasAitken/demo-fastapi-async-sqlalchemy/blob/main/backend/app/conftest.py
2
+
3
+ import asyncio
4
+ from contextlib import ExitStack
5
+
6
+ import pytest
7
+ from alembic.config import Config
8
+ from alembic.migration import MigrationContext
9
+ from alembic.operations import Operations
10
+ from alembic.script import ScriptDirectory
11
+ from config.index import config as settings
12
+ from app.engine.postgresdb import Base, get_db_session, postgresdb as sessionmanager
13
+ from main import app as actual_app
14
+ from asyncpg import Connection
15
+ from fastapi.testclient import TestClient
16
+
17
+
18
+ @pytest.fixture(autouse=True)
19
+ def app():
20
+ with ExitStack():
21
+ yield actual_app
22
+
23
+
24
+ @pytest.fixture
25
+ def client(app):
26
+ with TestClient(app) as c:
27
+ yield c
28
+
29
+
30
+ @pytest.fixture(scope="session")
31
+ def event_loop(request):
32
+ loop = asyncio.get_event_loop_policy().new_event_loop()
33
+ yield loop
34
+ loop.close()
35
+
36
+
37
+ def run_migrations(connection: Connection):
38
+ config = Config("alembic.ini")
39
+ config.set_main_option("script_location", "app/migration")
40
+ config.set_main_option("sqlalchemy.url", settings.SQLALCHEMY_TEST_DATABASE_URL)
41
+ script = ScriptDirectory.from_config(config)
42
+
43
+ def upgrade(rev, context):
44
+ return script._upgrade_revs("head", rev)
45
+
46
+ context = MigrationContext.configure(connection, opts={"target_metadata": Base.metadata, "fn": upgrade})
47
+
48
+ with context.begin_transaction():
49
+ with Operations.context(context):
50
+ context.run_migrations()
51
+
52
+
53
+ @pytest.fixture(scope="session", autouse=True)
54
+ async def setup_database():
55
+ # Run alembic migrations on test DB
56
+ async with sessionmanager.connect() as connection:
57
+ await connection.run_sync(run_migrations)
58
+
59
+ yield
60
+
61
+ # Teardown
62
+ await sessionmanager.close()
63
+
64
+
65
+ # Each test function is a clean slate
66
+ @pytest.fixture(scope="function", autouse=True)
67
+ async def transactional_session():
68
+ async with sessionmanager.session() as session:
69
+ try:
70
+ await session.begin()
71
+ yield session
72
+ finally:
73
+ await session.rollback() # Rolls back the outer transaction
74
+
75
+
76
+ @pytest.fixture(scope="function")
77
+ async def db_session(transactional_session):
78
+ yield transactional_session
79
+
80
+
81
+ @pytest.fixture(scope="function", autouse=True)
82
+ async def session_override(app, db_session):
83
+ async def get_db_session_override():
84
+ yield db_session[0]
85
+
86
+ app.dependency_overrides[get_db_session] = get_db_session_override
tests/pytest.ini ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ [pytest]
2
+ asyncio_mode = auto