Fastapi: [BUG] TestClient doesn't trigger startup event if app is imported from another module

Created on 2 Mar 2020  路  4Comments  路  Source: tiangolo/fastapi

Describe the bug

When using starlette's TestClient to test an application and importing the app module from a separate file, the startup events are not triggered.
However, it works as expected if you put everything in the same file/module.

To Reproduce

Steps to reproduce the behavior with a minimum self-contained file.

Replace each part with your own scenario:

  1. Create a main.py file with:
from fastapi import FastAPI, Request

app = FastAPI()


@app.get("/")
async def read_main():
    return {"msg": "Hello World"}


async def add_test_header(request: Request, call_next):
    response = await call_next(request)
    response.headers["X-Test-Header"] = 'Hello'
    return response


@app.on_event("startup")
def setup():
    # example code that runs on startup
    global add_test_header
    print('executing startup!!')
    add_test_header = app.middleware("http")(add_test_header)
  1. Create a test_startup.py file with:
from main import app
from fastapi.testclient import TestClient

client = TestClient(app)


def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"msg": "Hello World"}
    assert 'X-Test-Header' in response.headers
  1. Run pytest -s -v test_startup.py
  2. You will see an AssertionError for the X-Test-Header not being there
  3. The test should pass

Expected behavior

That test should pass, and we should see the result of the print('executing startup!!') in the output.

The funny thing is that the test does pass if you put everything in the same file.
You can verify that by creating a file with everything: cat main.py test_startup.py | grep -v 'from main' > test_all_together.py and then running with pytest -s -v test_all_together.py.

Screenshots

If applicable, add screenshots to help explain your problem.

Environment

  • OS: Linux
  • FastAPI Version: 0.52.0
python -c "import fastapi; print(fastapi.__version__)"
  • Python version: 3.6.9
bug

Most helpful comment

I have met this problem before and found this document:

https://fastapi.tiangolo.com/advanced/testing-events/

When you need your event handlers (startup and shutdown) to run in your tests, you can use the TestClient with a with statement:

All 4 comments

I have met this problem before and found this document:

https://fastapi.tiangolo.com/advanced/testing-events/

When you need your event handlers (startup and shutdown) to run in your tests, you can use the TestClient with a with statement:

i also saw it before

Thanks for the help here @hzmangel ! :clap: :bow:

@eliasdorneles your could would probably look something like this:

from main import app
from fastapi.testclient import TestClient

import pytest


@pytest.fixture
def client():
    with TestClient(app) as c:
        yield c


def test_read_main(client):
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"msg": "Hello World"}
    assert 'X-Test-Header' in response.headers

Right, that's a neat trick!
Thanks, I guess I'll close the issue, as it's well documented.
Sorry for the noise!

Was this page helpful?
0 / 5 - 0 ratings