Python / Uvicorn Fundamentals Interview Questions
How do you test a Uvicorn-served ASGI application without starting the server?
For unit and integration testing, you don't want to actually start a server and make HTTP requests. The httpx library's ASGITransport (or Starlette's TestClient) allows you to test ASGI applications in-process - no socket, no port, no server startup required.
# Using httpx.AsyncClient with ASGITransport (pure async test) import pytest import httpx from main import app @pytest.mark.anyio async def test_homepage(): async with httpx.AsyncClient( transport=httpx.ASGITransport(app=app), base_url="http://test" ) as client: response = await client.get("/") assert response.status_code == 200 assert response.json() == {"message": "Hello World"} # Using Starlette / FastAPI TestClient (sync interface, uses anyio) from fastapi.testclient import TestClient from main import app client = TestClient(app) def test_root(): response = client.get("/") assert response.status_code == 200 assert response.json() == {"message": "Hello World"} # Testing lifespan events with TestClient def test_with_lifespan(): with TestClient(app) as client: # lifespan startup has run at this point response = client.get("/") assert response.status_code == 200 # lifespan shutdown has run after the with block
Why this works: ASGI applications are just async callables - they can be called directly in tests without a server. The transport layer (httpx or Starlette's TestClient) converts Python test calls into ASGI scope/receive/send messages, running the application synchronously in the test process.
More Related questions...