Files
Tatami/tests/test_e2e_api.py
lars ba59235c3e Add opt-in live API end-to-end test
- test_e2e_api.py: minimal 2-address (4-element) call to the real Google
  Routes API; reads the real key from env/.env and skips on a placeholder.
- Marked `e2e` and deselected by default via addopts; run with
  `pytest -m e2e`.
2026-06-19 14:30:10 +02:00

68 lines
2.3 KiB
Python

"""Live end-to-end test against the real Google Routes API.
This is intentionally excluded from the default test run (it is marked ``e2e``
and ``addopts`` in pyproject.toml deselects that marker). It also costs billable
API elements, so it is kept minimal: two addresses -> a 2x2 (4-element) matrix.
Run it explicitly when you actually want to exercise the live API:
uv run pytest -m e2e
It requires a real GOOGLE_MAPS_API_KEY (read from the environment or the local
.env file); the test skips itself if only a placeholder/dummy key is available.
"""
import os
import pandas as pd
import pytest
from dotenv import load_dotenv
import tatami.traveltimes as tt
from tatami.classes import Participant
pytestmark = pytest.mark.e2e
# Values that are not a usable real key (conftest's dummy and the template value).
_PLACEHOLDER_KEYS = {"", "test-key", "your-api-key-here"}
def _real_api_key() -> str | None:
# Prefer a real value from the environment / .env over the dummy that conftest
# sets for the rest of the suite.
load_dotenv(override=True)
key = os.environ.get("GOOGLE_MAPS_API_KEY", "")
return key if key not in _PLACEHOLDER_KEYS else None
@pytest.fixture
def live_api(monkeypatch):
key = _real_api_key()
if key is None:
pytest.skip("No real GOOGLE_MAPS_API_KEY available; skipping live API test.")
# traveltimes captured the key at import time, so point the module global at
# the real key for this test.
monkeypatch.setattr(tt, "GOOGLE_MAPS_API_KEY", key)
return key
def test_live_route_matrix_minimal(live_api):
# Two real addresses -> a 2x2 matrix (4 billable elements), the smallest
# meaningful request.
participants = [
Participant("A", "Römerstr. 12, 76189 Karlsruhe", "", 10, ""),
Participant("B", "Gottesauerstr. 30, 76131 Karlsruhe", "", 10, ""),
]
matrix = tt.get_participant_distance_matrix(participants, mode="BICYCLE")
uuids = [p.uuid for p in participants]
assert matrix.shape == (2, 2)
assert list(matrix.index) == uuids
assert list(matrix.columns) == uuids
# A real bike trip between two distinct addresses takes a positive duration.
travel = matrix.loc[uuids[0], uuids[1]]
assert isinstance(travel, pd.Timedelta)
assert travel > pd.Timedelta(0)