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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions