Pytest plugin for aiohttp support providing fixtures for test server and client creation
npx @tessl/cli install tessl/pypi-pytest-aiohttp@1.1.0Pytest plugin for aiohttp support providing fixtures for test server and client creation. The plugin integrates with pytest-asyncio to enable comprehensive testing of aiohttp web applications and clients with automatic resource cleanup.
pip install pytest-aiohttpimport pytest
import pytest_aiohttpThe plugin is automatically loaded by pytest through the entry point system when pytest-aiohttp is installed. Individual fixtures are available directly in test functions without explicit imports:
async def test_example(aiohttp_client):
# fixture is available automatically
passFor direct access to Protocol classes or version information:
from pytest_aiohttp import AiohttpClient, AiohttpServer, AiohttpRawServer
import pytest_aiohttp
# Check version
print(pytest_aiohttp.__version__)import pytest
from aiohttp import web
async def hello(request):
return web.Response(body=b"Hello, world")
def create_app():
app = web.Application()
app.router.add_route("GET", "/", hello)
return app
async def test_hello(aiohttp_client):
client = await aiohttp_client(create_app())
resp = await client.get("/")
assert resp.status == 200
text = await resp.text()
assert "Hello, world" in textAdd asyncio_mode = auto to your pytest configuration file. The plugin also works with asyncio_mode = strict. The plugin automatically handles legacy mode migration with deprecation warnings.
# pytest.ini or setup.cfg
[tool:pytest]
asyncio_mode = autoCreates test clients for aiohttp applications and servers with automatic resource cleanup.
async def aiohttp_client(
app_or_server: Union[Application, BaseTestServer],
*,
server_kwargs: Optional[Dict[str, Any]] = None,
**kwargs: Any
) -> TestClient:
"""
Factory to create a TestClient instance.
Parameters:
- app_or_server: aiohttp Application or BaseTestServer instance
- server_kwargs: optional kwargs for server creation (when using Application)
- **kwargs: additional arguments passed to TestClient constructor
Returns:
TestClient instance with automatic cleanup
"""Usage examples:
# With Application
async def test_app(aiohttp_client):
app = web.Application()
client = await aiohttp_client(app)
# client is automatically cleaned up
# With server kwargs
async def test_custom_port(aiohttp_client, unused_tcp_port):
app = web.Application()
client = await aiohttp_client(app, server_kwargs={'port': unused_tcp_port})
assert client.port == unused_tcp_port
# With existing server
async def test_server(aiohttp_client, aiohttp_server):
app = web.Application()
server = await aiohttp_server(app)
client = await aiohttp_client(server)Creates test servers for aiohttp applications with configurable options.
async def aiohttp_server(
app: Application,
*,
host: str = "127.0.0.1",
port: Optional[int] = None,
**kwargs: Any
) -> TestServer:
"""
Factory to create a TestServer instance, given an app.
Parameters:
- app: aiohttp Application instance
- host: server host address (default: "127.0.0.1")
- port: server port (optional, auto-assigned if None)
- **kwargs: additional arguments passed to start_server()
Returns:
TestServer instance with automatic cleanup
"""Usage example:
async def test_server(aiohttp_server):
app = web.Application()
app.router.add_get('/', lambda r: web.Response(text='OK'))
server = await aiohttp_server(app, port=8080)
assert server.port == 8080
# server is automatically cleaned upCreates raw test servers for testing with custom request handlers.
async def aiohttp_raw_server(
handler: _RequestHandler,
*,
port: Optional[int] = None,
**kwargs: Any
) -> RawTestServer:
"""
Factory to create a RawTestServer instance, given a web handler.
Parameters:
- handler: request handler function
- port: server port (optional, auto-assigned if None)
- **kwargs: additional arguments passed to start_server()
Returns:
RawTestServer instance with automatic cleanup
"""Usage example:
from aiohttp import web
async def handler(request):
return web.Response(text="OK")
async def test_raw_server(aiohttp_raw_server, aiohttp_client):
server = await aiohttp_raw_server(handler)
client = await aiohttp_client(server)
resp = await client.get('/')
assert resp.status == 200Allows customization of the TestClient class used by aiohttp_client.
def aiohttp_client_cls() -> Type[TestClient]:
"""
Client class to use in aiohttp_client factory.
Returns:
TestClient class or subclass
Default: TestClient
"""Usage example:
from aiohttp.test_utils import TestClient
class MyClient(TestClient):
async def login(self, *, user, pw):
payload = {"username": user, "password": pw}
return await self.post("/login", json=payload)
@pytest.fixture
def aiohttp_client_cls():
return MyClient
async def test_login(aiohttp_client):
app = web.Application()
client = await aiohttp_client(app)
await client.login(user="admin", pw="s3cr3t")The following Protocol classes are directly importable from the pytest_aiohttp module:
from typing import Protocol, Union, Dict, Any, Optional, Awaitable, Type
from aiohttp.web import Application, BaseRequest
from aiohttp.test_utils import TestClient, TestServer, RawTestServer, BaseTestServer
from aiohttp.web_protocol import _RequestHandler
class AiohttpClient(Protocol):
"""Protocol for aiohttp_client fixture."""
async def __call__(
self,
app_or_server: Union[Application, BaseTestServer],
*,
server_kwargs: Optional[Dict[str, Any]] = None,
**kwargs: Any
) -> TestClient: ...
class AiohttpServer(Protocol):
"""Protocol for aiohttp_server fixture."""
def __call__(
self, app: Application, *, port: Optional[int] = None, **kwargs: Any
) -> Awaitable[TestServer]: ...
class AiohttpRawServer(Protocol):
"""Protocol for aiohttp_raw_server fixture."""
def __call__(
self,
handler: _RequestHandler,
*,
port: Optional[int] = None,
**kwargs: Any
) -> Awaitable[RawTestServer]: ...These Protocol classes can be imported directly for type annotations:
from pytest_aiohttp import AiohttpClient, AiohttpServer, AiohttpRawServer
def my_test_helper(client_factory: AiohttpClient) -> None:
# Use the client factory with proper typing
passThe plugin automatically handles cleanup of resources (clients and servers) when tests complete or fail. If server creation fails, appropriate exceptions are propagated:
RuntimeError: Raised when application factory fails__version__: str
"""Package version string."""Usage example:
import pytest_aiohttp
print(f"pytest-aiohttp version: {pytest_aiohttp.__version__}")