question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Test client usage question: how to trigger lifespan startup and shutdown ?

See original GitHub issue

I have an issue switching from the TestClient from async_asgi_testclient to the httpx.AsyncClient : the startup and shutdown events of my app aren’t triggered by the latter.

It’s probably a bad usage on my end, but if anyone could pinpoint what I’m doing wrong it would be of tremendous help,

I wrote a small set of 2 tests below to better describe the situation, the one with httpx.AsyncClient fails while the other passes fine:

import logging

import pytest
from async_asgi_testclient import TestClient
from httpx import AsyncClient
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

app = Starlette()


@app.on_event("startup")
async def startup():
    logger.debug("starting the app")


@app.on_event("shutdown")
async def shutdown():
    logger.debug("shutdown the app")


@app.route("/")
def homepage(request: Request):
    logger.debug("HOME")
    return JSONResponse({"hello": "world"})


@pytest.fixture
async def asyncasgitestclient():
    yield TestClient(app)


@pytest.fixture
async def httpxclient():
    yield AsyncClient(app=app, base_url="https://domain.tld")


@pytest.mark.asyncio
async def test_homepage_with_httpxclient(httpxclient, caplog):
    async with httpxclient:
        url = app.url_path_for("homepage")
        resp = await httpxclient.get(url)
        assert resp.status_code == 200
        assert resp.json() == {"hello": "world"}
    logger.debug(caplog.messages)
    assert all(
        x in caplog.messages for x in ["starting the app", "HOME", "shutdown the app"]
    )


@pytest.mark.asyncio
async def test_homepage_with_async_asgi_testclient(asyncasgitestclient, caplog):
    async with asyncasgitestclient:
        url = app.url_path_for("homepage")
        resp = await asyncasgitestclient.get(url)
        assert resp.status_code == 200
        assert resp.json() == {"hello": "world"}
    logger.debug(caplog.messages)
    assert all(
        x in caplog.messages for x in ["starting the app", "HOME", "shutdown the app"]
    )

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:16 (15 by maintainers)

github_iconTop GitHub Comments

3reactions
florimondmancacommented, Sep 27, 2019

Okay so, I created https://github.com/florimondmanca/asgi-lifespan to experiment on this. It’s mostly empty for now but I’ll add LifespanContext based on the implementation in #352, and I plan to have LifespanMiddleware be mostly ripped out from Starlette.

Any thoughts on the proposed API there?

2reactions
sethmlarsoncommented, Sep 27, 2019

Dropping in just to say that it’s a bummer that a full ASGI use-case can’t be solved with just HTTPX. IMO this is one of our defining features as an HTTP client in the ecosystem.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to trigger lifespan startup and shutdown while testing ...
For this, you need to use LifespanManager . Install: pip install asgi_lifespan. The code would be like so: import pytest from asgi_lifespan ...
Read more >
Testing Events: startup - shutdown - FastAPI
When you need your event handlers ( startup and shutdown ) to run in your tests, you can use the TestClient with a...
Read more >
Test Client - Starlette
If you want the TestClient to run lifespan events ( on_startup , on_shutdown , or lifespan ), you will need to use the...
Read more >
Understanding and Handling Connection Lifetime Events in ...
This article describes how to use the events that are exposed by the Hubs API.
Read more >
falcon.testing.client — Falcon 3.1.1 documentation
TestClient (app) response_one = client.simulate_get('/') response_two ... app lifecycle in a single shot, including lifespan and client disconnect events.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found