Problem
Tests connect to the dev database (ocotilloapi_dev) instead of the test database (ocotilloapi_test) because multiple load_dotenv(override=True) calls stomp env vars set by the test framework. There are 7 load_dotenv calls across the codebase with inconsistent override behavior:
| File |
Call |
Override |
tests/__init__.py:23 |
load_dotenv(override=True) |
Yes |
tests/conftest.py:7 |
load_dotenv(override=True) |
Yes |
db/engine.py:35 |
load_dotenv(override=False) |
No |
alembic/env.py:47 |
load_dotenv() |
No (default) |
main.py:7 |
load_dotenv() |
No (default) |
cli/cli.py:28 |
load_dotenv(override=True) |
Yes |
transfers/transfer.py:39 |
load_dotenv(override=False) |
No |
The override=True calls re-read .env (which has POSTGRES_DB=ocotilloapi_dev) and overwrite the test framework's POSTGRES_DB=ocotilloapi_test.
Proposed fix: follow standard Python convention
The standard convention in the Python/FastAPI ecosystem:
-
load_dotenv() (no override) everywhere — .env provides defaults, not overrides. Env vars already set by the runtime, test framework, or CI take precedence. This is the default behavior of python-dotenv for a reason.
-
Set test env vars before load_dotenv() — in tests/__init__.py, set POSTGRES_DB=ocotilloapi_test before calling load_dotenv(). Since the default is no-override, .env's value won't stomp it.
-
One load_dotenv() per entry point — main.py, cli/cli.py, tests/__init__.py, transfers/transfer.py each call it once. Library code (db/engine.py) and Alembic (env.py) should NOT call load_dotenv() — they rely on the entry point having loaded it.
Concrete changes
tests/__init__.py: set POSTGRES_DB=ocotilloapi_test before load_dotenv(), remove override=True
tests/conftest.py: remove load_dotenv call entirely, remove TEST_DATABASE_NAME / _test_database_url()
db/engine.py: remove load_dotenv(override=False) (entry points handle it)
alembic/env.py: remove load_dotenv() (entry points handle it)
cli/cli.py: change override=True to plain load_dotenv()
transfers/transfer.py: simplify override=False to plain load_dotenv()
main.py: already correct, no change
Problem
Tests connect to the dev database (
ocotilloapi_dev) instead of the test database (ocotilloapi_test) because multipleload_dotenv(override=True)calls stomp env vars set by the test framework. There are 7load_dotenvcalls across the codebase with inconsistentoverridebehavior:tests/__init__.py:23load_dotenv(override=True)tests/conftest.py:7load_dotenv(override=True)db/engine.py:35load_dotenv(override=False)alembic/env.py:47load_dotenv()main.py:7load_dotenv()cli/cli.py:28load_dotenv(override=True)transfers/transfer.py:39load_dotenv(override=False)The
override=Truecalls re-read.env(which hasPOSTGRES_DB=ocotilloapi_dev) and overwrite the test framework'sPOSTGRES_DB=ocotilloapi_test.Proposed fix: follow standard Python convention
The standard convention in the Python/FastAPI ecosystem:
load_dotenv()(no override) everywhere —.envprovides defaults, not overrides. Env vars already set by the runtime, test framework, or CI take precedence. This is the default behavior ofpython-dotenvfor a reason.Set test env vars before
load_dotenv()— intests/__init__.py, setPOSTGRES_DB=ocotilloapi_testbefore callingload_dotenv(). Since the default is no-override,.env's value won't stomp it.One
load_dotenv()per entry point —main.py,cli/cli.py,tests/__init__.py,transfers/transfer.pyeach call it once. Library code (db/engine.py) and Alembic (env.py) should NOT callload_dotenv()— they rely on the entry point having loaded it.Concrete changes
tests/__init__.py: setPOSTGRES_DB=ocotilloapi_testbeforeload_dotenv(), removeoverride=Truetests/conftest.py: removeload_dotenvcall entirely, removeTEST_DATABASE_NAME/_test_database_url()db/engine.py: removeload_dotenv(override=False)(entry points handle it)alembic/env.py: removeload_dotenv()(entry points handle it)cli/cli.py: changeoverride=Trueto plainload_dotenv()transfers/transfer.py: simplifyoverride=Falseto plainload_dotenv()main.py: already correct, no change