Testing¶
The in-memory test clients.
TestClient
¶
Sync test client - drives the app through its ASGI surface.
Usage::
client = TestClient(app)
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"message": "ok"}
cookies
property
¶
Live view of the client's cookie jar.
Supports dict-like access (client.cookies["session"]),
assignment (client.cookies["k"] = "v"), deletion, iteration,
and bulk clear(). Cookies the server sends on responses are
automatically merged in via _update_cookies. The state
persists across calls until the client is closed.
set_cookie
¶
Add or update a cookie sent on every subsequent request.
session_transaction
¶
Mutate the session outside a request.
Yields a Session dict pre-loaded from the current session
cookie (if any). On block exit the session is re-signed with the
app's SessionMiddleware secret and stored in the cookie jar, so
the next request carries it::
with client.session_transaction() as sess:
sess["user_id"] = 7
Raises RuntimeError if the app has no SessionMiddleware.
get
¶
get(path: str, headers: dict[str, str] | None = None, params: dict[str, str] | Sequence[tuple[str, str]] | None = None, follow_redirects: bool | None = None) -> TestResponse
Send a GET request and return the response.
post
¶
post(path: str, json: Any = None, data: dict[str, str] | None = None, headers: dict[str, str] | None = None, content: bytes | None = None, files: dict[str, Any] | None = None, follow_redirects: bool | None = None, stream: Any | None = None) -> TestResponse
Send a POST. stream feeds the body as multiple http.request
chunks (a sync Iterable or AsyncIterable of bytes/str); when
given it takes precedence over and excludes json/data/content/files.
put
¶
put(path: str, json: Any = None, data: dict[str, str] | None = None, headers: dict[str, str] | None = None, content: bytes | None = None, files: dict[str, Any] | None = None, follow_redirects: bool | None = None, stream: Any | None = None) -> TestResponse
Send a PUT. See post for the stream chunked-body parameter.
patch
¶
patch(path: str, json: Any = None, data: dict[str, str] | None = None, headers: dict[str, str] | None = None, content: bytes | None = None, files: dict[str, Any] | None = None, follow_redirects: bool | None = None, stream: Any | None = None) -> TestResponse
Send a PATCH. See post for the stream chunked-body parameter.
delete
¶
delete(path: str, headers: dict[str, str] | None = None, follow_redirects: bool | None = None) -> TestResponse
Send a DELETE request and return the response.
head
¶
head(path: str, headers: dict[str, str] | None = None, follow_redirects: bool | None = None) -> TestResponse
Send a HEAD request and return the response.
options
¶
options(path: str, headers: dict[str, str] | None = None, follow_redirects: bool | None = None) -> TestResponse
Send an OPTIONS request and return the response.
request
¶
request(method: str, path: str, json: Any = None, data: dict[str, str] | None = None, headers: dict[str, str] | None = None, content: bytes | None = None, files: dict[str, Any] | None = None, params: dict[str, str] | Sequence[tuple[str, str]] | None = None, follow_redirects: bool | None = None, stream: Any | None = None) -> TestResponse
Generic request dispatcher - httpx/test-client shape.
client.request("PATCH", "/x", json=...) is the verb-agnostic
form of client.get / client.post / .... Bodies (json /
data / content / files / stream) and params are handled
exactly as the per-verb methods do; stream (see post) excludes
the buffered body forms.
websocket_connect
¶
websocket_connect(path: str, subprotocols: list[str] | None = None, headers: dict[str, str] | None = None) -> _WebSocketSession
Open an in-memory WebSocket against the app - context manager.
Drives the ASGI websocket protocol: synthesise the scope, send
websocket.connect, route to the handler, then forward
send_text / receive_text / close calls to the running
handler through a pair of asyncio queues.
AsyncTestClient
¶
Async in-memory test client - drives the app through its ASGI surface.
The async counterpart of TestClient: used as an async context
manager inside an async test, so each request is awaited on the
test's own running event loop instead of through a private loop. The
request methods (get / post / ...) are coroutines.
Usage::
async with AsyncTestClient(app) as client:
resp = await client.get("/")
Cookie persistence, redirect following, and the JSON / form / files
body shapes match TestClient exactly. WebSocket testing stays on
the sync TestClient.websocket_connect.
cookies
property
¶
Live view of the client's cookie jar (see TestClient.cookies).
set_cookie
¶
Add or update a cookie sent on every subsequent request.
get
async
¶
get(path: str, headers: dict[str, str] | None = None, params: dict[str, str] | Sequence[tuple[str, str]] | None = None, follow_redirects: bool | None = None) -> TestResponse
Send a GET request and return the response.
post
async
¶
post(path: str, json: Any = None, data: dict[str, str] | None = None, headers: dict[str, str] | None = None, content: bytes | None = None, files: dict[str, Any] | None = None, follow_redirects: bool | None = None, stream: Any | None = None) -> TestResponse
Send a POST. stream feeds the body as multiple http.request
chunks (a sync Iterable or AsyncIterable of bytes/str); when
given it takes precedence over and excludes json/data/content/files.
put
async
¶
put(path: str, json: Any = None, data: dict[str, str] | None = None, headers: dict[str, str] | None = None, content: bytes | None = None, files: dict[str, Any] | None = None, follow_redirects: bool | None = None, stream: Any | None = None) -> TestResponse
Send a PUT. See post for the stream chunked-body parameter.
patch
async
¶
patch(path: str, json: Any = None, data: dict[str, str] | None = None, headers: dict[str, str] | None = None, content: bytes | None = None, files: dict[str, Any] | None = None, follow_redirects: bool | None = None, stream: Any | None = None) -> TestResponse
Send a PATCH. See post for the stream chunked-body parameter.
delete
async
¶
delete(path: str, headers: dict[str, str] | None = None, follow_redirects: bool | None = None) -> TestResponse
Send a DELETE request and return the response.
head
async
¶
head(path: str, headers: dict[str, str] | None = None, follow_redirects: bool | None = None) -> TestResponse
Send a HEAD request and return the response.
options
async
¶
options(path: str, headers: dict[str, str] | None = None, follow_redirects: bool | None = None) -> TestResponse
Send an OPTIONS request and return the response.
request
async
¶
request(method: str, path: str, json: Any = None, data: dict[str, str] | None = None, headers: dict[str, str] | None = None, content: bytes | None = None, files: dict[str, Any] | None = None, params: dict[str, str] | Sequence[tuple[str, str]] | None = None, follow_redirects: bool | None = None, stream: Any | None = None) -> TestResponse
Generic verb-agnostic request dispatcher (see TestClient.request).