Skip to content

test(main): fix route-registration tests for FastAPI >=0.138 - #37

Merged
timothybrown merged 1 commit into
mainfrom
fix/test-main-route-iteration
Jun 29, 2026
Merged

timothybrown merged 1 commit into
mainfrom
fix/test-main-route-iteration

Conversation

@timothybrown

Copy link
Copy Markdown
Owner

Problem

The backend Dependabot PRs (#33 starlette, #36 pydantic-settings) fail CI on two tests:

tests/test_main.py::TestAppRoutes::test_api_routes_registered     - AttributeError: '_IncludedRouter' object has no attribute 'path'
tests/test_main.py::TestAppRoutes::test_websocket_route_registered - AttributeError: '_IncludedRouter' object has no attribute 'path'

Root cause

This is not a problem with either dependency. CI installs the backend with uv pip install -e ".[dev]", which ignores uv.lock and resolves fresh from PyPI — so it picks up FastAPI 0.138.x. In 0.138, include_router() no longer flattens sub-routes into app.routes; instead it inserts opaque _IncludedRouter wrapper objects that have no .path. The tests did [r.path for r in app.routes], which now throws.

Because the backend Dependabot PRs trigger backend CI (path-scoped), they surface the failure; main would fail the same way if its backend CI re-ran.

Fix

Assert against public, version-stable APIs instead of FastAPI's internal route objects:

  • HTTP routes → app.openapi()["paths"]
  • WebSocket route → app.url_path_for("websocket_live") (WebSockets aren't in the OpenAPI schema)

Deliberately avoids the private _IncludedRouter / effective_route_contexts internals — depending on those is what made the test brittle in the first place.

Verification

  • ✅ Full backend suite (251 tests) passes on FastAPI 0.138.1 (the version CI resolves)
  • ✅ test_main.py passes on the locked FastAPI 0.135.3 / Starlette 1.0.1
  • ✅ ruff clean

Once merged, #33 and #36 just need a rebase to go green.

🤖 Generated with Claude Code

FastAPI >=0.138 no longer flattens included routers into app.routes;
they become opaque _IncludedRouter wrappers without a .path attribute,
so `[r.path for r in app.routes]` raised AttributeError. CI resolves
deps fresh from PyPI, so it picked up FastAPI 0.138.x and these two
tests started failing (blocking the starlette and pydantic-settings
Dependabot PRs).

Assert HTTP routes against app.openapi()["paths"] and the WebSocket
route via app.url_path_for("websocket_live") — both public, version-
stable APIs. Verified passing on FastAPI 0.135.3 (locked) and 0.138.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xQgiPUb99rkTtZHoFncEh
@timothybrown
timothybrown merged commit effee5f into main Jun 29, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant