Pytest plugin for aiohttp support providing fixtures for test server and client creation
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Pytest 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__}")