Newsletter
TechAnV Blog
Get updates on security engineering, Rust, eBPF, and DevSecOps. No spam, unsubscribe anytime.
Check your inbox and click the confirmation link to complete your subscription.
Writing tests for the ASGI lifespan protocol with HTTPX#
Uvicorn silently ignores exceptions that occur during startup against the ASGI lifespan protocol - see starlette/issues/486.
You can disable this feature using the lifespan="on" parameter to uvicorn.run() - which Datasette now does as-of 16f592247a2a0e140ada487e9972645406dcae69
This exposed a bug in datasette-debug-asgi: it wasn’t handling lifespan events correctly. datasette-debug-asgi/issues/1
The unit tests weren’t catching this because using HTTPX to make test requests doesn’t trigger lifespan events.
Florimond Manca had run into this problem too, and built asgi-lifespan to address it.
You can wrap an ASGI app in async with LifespanManager(app): and the correct lifespan events will be fired by that with block.
Here’s how to use it to trigger lifespan events in a test:
1from asgi_lifespan import LifespanManager2
3@pytest.mark.asyncio4async def test_datasette_debug_asgi():5 ds = Datasette([], memory=True)6 app = ds.app()7 async with LifespanManager(app):8 async with httpx.AsyncClient(app=app) as client:9 response = await client.get("http://localhost/-/asgi-scope")10 assert 200 == response.status_code11 assert "text/plain; charset=UTF-8" == response.headers["content-type"]