Skip to content

Test DB setup should follow standard Python load_dotenv convention #585

@kbighorse

Description

@kbighorse

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:

  1. 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.

  2. 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.

  3. One load_dotenv() per entry pointmain.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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions