Skip to content

fix(testing): route-introspection tests for FastAPI 0.137 lazy include_router - #212

Merged
antosubash merged 1 commit into
mainfrom
fix-fastapi-0137-route-tests
Jun 16, 2026
Merged

fix(testing): route-introspection tests for FastAPI 0.137 lazy include_router#212
antosubash merged 1 commit into
mainfrom
fix-fastapi-0137-route-tests

Conversation

@antosubash

Copy link
Copy Markdown
Owner

Problem

The full Python suite currently has 2 failing tests on main:

  • framework/hosting/tests/test_app.py::TestRouteRegistration::test_expected_routes_registered
  • framework/testing/tests/test_app_factory.py::TestBuildTestApp::test_registers_module_routes_with_prefix
AssertionError: assert '/health' in ['/openapi.json']
AssertionError: assert '/api/echo/ping' in {None, '/redoc', '/docs', '/openapi.json'}

Root cause

FastAPI 0.137 / Starlette 1.3 made include_router() lazy. Included routes are no longer eagerly flattened into app.routes; each include_router() now leaves a private _IncludedRouter wrapper that carries no .path and resolves its routes only at request time. Any code that enumerates app.routes by .path therefore no longer sees module API/view routes or the health router.

The routes still work at runtime — every request-based test (1300+) passes, and the app serves all routes — so this is purely a static-introspection break in the test helpers. It surfaced now via dependency drift (the suite was green on these tests at the last release; a FastAPI/Starlette bump since then flipped the behaviour).

Fix

  • Add simple_module_test.effective_route_paths(app) — enumerates routes via the OpenAPI schema (a stable public API that lists every schema route with its fully-resolved prefix), unioned with any top-level mounts (StaticFiles). Version-agnostic across the eager→lazy change.
  • Switch the affected hosting/testing route tests to use it. As a bonus, the absence assertions (test_isolates_from_other_installed_modules, test_modules_enabled_limits_loaded_modules) become meaningful again — under lazy inclusion they had started passing vacuously (the routes they checked for were hidden in the wrappers).
  • The dashboard's bare-prefix Inertia alias (/dashboard, registered include_in_schema=False) isn't enumerable via OpenAPI; its behaviour stays covered by TestProtectedPages::test_dashboard_redirects_unauthenticated.

Verification

  • Full Python suite: 1345 passed, 0 failed (was 1343 passed / 2 failed).
  • ruff check + ruff format --check + ty on the touched packages — clean.

This is the pre-existing red that also makes other PRs' CI fail (e.g. #211); merging it first turns the suite green for everyone.

…e_router

FastAPI 0.137 / Starlette 1.3 made `include_router()` lazy: included routes no
longer appear in `app.routes` (they sit behind `_IncludedRouter` wrappers and
resolve only at request time). Tests that introspected `app.routes` by `.path`
stopped seeing module/health routes — so `test_expected_routes_registered` and
`test_registers_module_routes_with_prefix` failed even though the routes still
work at runtime. (Surfaced via dependency drift since the last green run.)

- Add `simple_module_test.effective_route_paths(app)`: reads the OpenAPI schema
  (fully-resolved prefixes) unioned with top-level mounts — version-agnostic,
  and the supported way to assert on registered routes.
- Use it in the affected hosting/testing route tests; the absence assertions
  (`test_isolates_*`, `test_modules_enabled_*`) become meaningful again instead
  of passing vacuously under lazy inclusion.

The dashboard's bare-prefix Inertia alias is `include_in_schema=False`; its
behaviour stays covered by `TestProtectedPages`.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying simple-module-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: ccea332
Status: ✅  Deploy successful!
Preview URL: https://fdb7e95b.simple-module-python.pages.dev
Branch Preview URL: https://fix-fastapi-0137-route-tests.simple-module-python.pages.dev

View logs

@antosubash
antosubash merged commit eb4686a into main Jun 16, 2026
12 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