{"id":7941,"library":"async-asgi-testclient","title":"Async ASGI TestClient","description":"Async ASGI TestClient is a framework-agnostic library for testing web applications that implement the ASGI specification (versions 2 and 3). It allows direct interaction with an ASGI application within the same asyncio loop as the tests, eliminating the need for a separate HTTP server. Inspired by Quart's testing module, it supports features like cookies, multipart/form-data, redirects, and streaming for both requests and responses, as well as websocket testing. The current version is 1.4.11.","status":"active","version":"1.4.11","language":"en","source_language":"en","source_url":"https://github.com/vinissimus/async-asgi-testclient","tags":["testing","asgi","asyncio","quart","starlette","fastapi","web-testing","python3"],"install":[{"cmd":"pip install async-asgi-testclient","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"TestClient","correct":"from async_asgi_testclient import TestClient"}],"quickstart":{"code":"import pytest\nfrom quart import Quart, jsonify\nfrom async_asgi_testclient import TestClient\n\n# A dummy ASGI app for testing\napp = Quart(__name__)\n\n@app.route('/')\nasync def root():\n    return 'plain response'\n\n@app.route('/json')\nasync def json_endpoint():\n    return jsonify({\"hello\": \"world\"})\n\n@pytest.mark.asyncio\nasync def test_quart_app():\n    async with TestClient(app) as client:\n        # Test GET request to root\n        resp = await client.get(\"/\")\n        assert resp.status_code == 200\n        assert resp.text == \"plain response\"\n\n        # Test GET request to JSON endpoint\n        resp = await client.get(\"/json\")\n        assert resp.status_code == 200\n        assert resp.json() == {\"hello\": \"world\"}","lang":"python","description":"Demonstrates how to test a simple Quart (ASGI) application using `async-asgi-testclient` with `pytest` and `pytest-asyncio`. The `TestClient` is used as an async context manager to send requests and assert responses."},"warnings":[{"fix":"Ensure your tests are fully asynchronous when interacting with async resources within an `async def` test. If using a framework's built-in `TestClient` which has a synchronous interface, be mindful of its underlying implementation and potential sync-async bridges. `async-asgi-testclient` inherently supports an async context.","message":"Mixing synchronous `TestClient` instances (from frameworks like Starlette/FastAPI's built-in `TestClient`) with asynchronous test functions that access other async resources (e.g., database connections) can lead to event loop errors due to context mixing. `async-asgi-testclient` is designed to be fully asynchronous.","severity":"gotcha","affected_versions":"All versions (general async testing principle)"},{"fix":"Prefer `async with client.ws_session(...)` for WebSocket tests to ensure connections are properly managed. If using `websocket = await client.ws_connect(...)`, explicitly call `await websocket.close()` afterwards.","message":"When testing WebSocket connections, ensure proper closure. The `TestClient`'s `ws_session` method handles closing via an `async with` context manager, but if using `ws_connect` directly, you must call `websocket.close()` manually.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Review FastAPI routing configuration. If encountering this, consider simplifying routing or investigating if a more direct `TestClient` initialization with the final ASGI app resolves the issue. (Refer to GitHub issue #62 for updates).","message":"Some users have reported issues with `TestClient` when a FastAPI application uses `APIRouter().add_api_router()` for routing, leading to incorrect method calls.","severity":"gotcha","affected_versions":"Potentially 1.x.x, reported in 1.3.x context"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"When writing `async def` tests, ensure all async operations are part of the same event loop. `async-asgi-testclient` itself runs within the test's event loop, so this error is less likely with this specific library unless other async components introduce a separate loop. If using other `TestClient` implementations, switch to an `AsyncClient` from `httpx` with `ASGITransport` if you need to perform multiple async operations within the same test function.","cause":"Attempting to use asynchronous resources (like database connections or other async clients) within an `async def` test function that itself uses a testing client (like `Starlette.TestClient` or `FastAPI.TestClient`) that creates its own internal event loop or sync-to-async bridge. This is not specific to `async-asgi-testclient` but a common pattern problem.","error":"RuntimeError: Task <Task ...> got Future <Future ...> attached to a different loop"},{"fix":"This is an active issue. Possible workarounds might involve refactoring routing to be more direct, or ensuring the ASGI application passed to `TestClient` is the final, fully configured app. Check GitHub issues for `async-asgi-testclient` for status or community-provided solutions.","cause":"Specific routing configurations within FastAPI using `APIRouter().add_api_router()` may not be correctly interpreted by `async-asgi-testclient` in some scenarios.","error":"TestClient calls wrong method when fastapi.APIRouter().add_api_router() is used to setup the router"},{"fix":"This is an open issue. Ensure you are on a version of `async-asgi-testclient` that explicitly supports your Starlette version for streaming. If the problem persists, check the GitHub repository for updates or specific version recommendations.","cause":"Compatibility issues between `async-asgi-testclient`'s streaming handling and updates in newer Starlette versions.","error":"Streaming not working with newer versions of starlette"},{"fix":"This is an open issue. When testing WebSocket rejections, examine the ASGI application's logic for rejecting connections and the `TestClient`'s response. You might need to inspect lower-level attributes of the response object or application logs for more details.","cause":"The `TestClient` may not correctly process or expose reasons for rejected WebSocket connections from the ASGI application.","error":"Client unable to handle websocket connection rejections"}]}