[Question] Async test client
See original GitHub issueI’m developing an app that requires async setup and teardown during testing. For example, I insert data into a Redis database using aioredis. I’m using pytest-asyncio to mark async test functions.
The test client uses the synchronous requests API and an ASGI adapter to call the Starlette app. The setup I described above doesn’t work with the adapter because it doesn’t expect an event loop to be running.
I haven’t worked with asyncio prior to using Starlette so I may be missing something obvious but do you have any suggestions for how to deal with this? I thought about more explicitly managing the event loop during testing but this seemed a bit tedious.
Another option was an async test client. I had a look at aiohttp and if a custom Connector
could be used in place of the ASGI requests adapter but I didn’t spend much time on it.
For now, I cobbled together an async test client that combines the request setup from requests.Session
and starlette.testclient. _ASGIAdapter
.
By the way, if there’s a better place to ask questions, please let me know 😄
Issue Analytics
- State:
- Created 5 years ago
- Comments:9 (6 by maintainers)
Top GitHub Comments
I’ll just put links here for future strangers.
Also awesome explanation about the async test client: https://fastapi.tiangolo.com/advanced/async-tests/ (it’s about FastAPI but it still should be applicable to pure Starlette).
My example of async test client fixture:
@mackeyja92 Here’s a gist: https://gist.github.com/ryankask/90c0dc155d3f95a52a1eaa0ac4ef63d0.
I needed to make it async all the way down to this call
loop.run_until_complete(connection(receive, send))
deep in the adapter so a nested loop wasn’t started.To do this, I combined the ASGI adapter Tom wrote with requests’ Session API. I removed some of the Session-related code that I didn’t think was relevant but I may have removed or left in too much.
I use pytest with pytest-asyncio doing something like this
All my app code is async so to test in same way I’ve always done (arrange, act, assert, this time asynchronously), I think I need an async test client. This way pytest-asyncio can manage the loop and I can use pytest naturally. Maybe I need to just change the way I test so hopefully someone points out a better way.
I thought it would be better to use aiohttp’s equivalent of a requests’ adapter but I didn’t spend much time figuring it out.