149 words
1 minute
Writing tests for the ASGI lifespan protocol with HTTPX
Anubhav Gain
2024-06-02

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:

from asgi_lifespan import LifespanManager
@pytest.mark.asyncio
async def test_datasette_debug_asgi():
ds = Datasette([], memory=True)
app = ds.app()
async with LifespanManager(app):
async with httpx.AsyncClient(app=app) as client:
response = await client.get("http://localhost/-/asgi-scope")
assert 200 == response.status_code
assert "text/plain; charset=UTF-8" == response.headers["content-type"]
Writing tests for the ASGI lifespan protocol with HTTPX
https://mranv.pages.dev/posts/writing-tests-for-the-asgi-lifespan-protocol-with-httpx/
Author
Anubhav Gain
Published at
2024-06-02
License
CC BY-NC-SA 4.0