Open Ian-Hart opened 2 years ago
Thank you very much!
Thank you very much, M1 is really good but also very painful, I also spent whole day to figure out the reason. and for "OAuth2PasswordRequestForm" use "form" instead of "data" in the async_asgi_testclient
I'm also having concurrency issues in dockerized exection on M1. async_asgi_testclient
TestClient
helps with timing out issue.
Another problem is pytest.fixture
decorated co-routines either miss attributes (see: this question) or are not detected at all. As indicated in the top answer, pytest_asyncio.fixture
solved all issues.
thanks!
In my case i had to also update @pytest_asyncio.fixture
:
# Make requests in our tests
@pytest_asyncio.fixture
async def client(app: FastAPI) -> TestClient:
async with TestClient(app) as client:
yield client
I enjoyed this Fastapi series and had everything working until I updated my computer from Mac Pro 2015 to Mac Air (M1). From there I experienced unexplained concurrency and time out errors when running pytest. Tests would sometimes work other times fail. After several days of trial and error I narrowed the issue to httpx AsyncClient or LIfespan manager. Sharing the solution in case anyone else has the same issue.
1) Updated requirement.txts to add async_asgi_testclient and remove httpx and asgi-lifespan
fastapi==0.65.0 uvicorn==0.15.0 pydantic==1.4 email-validator== 1.1.1
databases[postgresql]==0.5.3 SQLAlchemy==1.4.27 alembic== 1.7.5 psycopg2-binary==2.9.2
pytest== 6.2.5 pytest-asyncio== 0.16.0 async_asgi_testclient==1.4.7
2) Updated the client in conftest.py to async_asgi_testclient
from async_asgi_testclient import TestClient
@pytest.fixture async def client(app: FastAPI) -> TestClient: async with TestClient(app) as client: yield client
3) Updated the tests to use the TestClient. For instance in test_cleanings.py
from async_asgi_testclient import TestClient
class TestCreateCleaning: async def test_valid_input_creates_cleaning( self, app: FastAPI, client: TestClient, new_cleaning: CleaningCreate ) -> None: res = await client.post( app.url_path_for("cleanings:create-cleaning"), headers={"Content-Type": "application/json"}, json={"new_cleaning": new_cleaning.dict()} ) assert res.status_code == HTTP_201_CREATED