litestar-org/litestar-skills/litestar-testing
Claude Code and agent skill by litestar-org/litestar-skills
- community
Checking that the SKILL.md file is still in the repository.
Use when working with test_*.py, conftest.py, litestar.testing, TestClient, AsyncTestClient, create_test_client, create_async_test_client, anyio, Guard mocks, or DI overrides. Not for generic pytest.
Install
npx vskill@latest install litestar-org/litestar-skills/litestar-testingSKILL.md
litestar-testing
Litestar-specific testing patterns built on pytest + anyio. Covers:
TestClientvsAsyncTestClient— constructor options, lifespan, and when to use eachcreate_test_clientandcreate_async_test_client— inline app factories for isolated handler/controller tests@pytest.mark.anyiosetup andpytest-asynciocoexistence rules- App + lifespan fixtures (
on_startup/on_shutdown/lifespan) - Mocking Guards and overriding DI dependencies (native
Provideand DishkaProvider) - Session testing with
set_session_dataandget_session_data - WebSocket testing with
websocket_connectandWebSocketTestSession - Unit-testing Guards and dependencies with
RequestFactory - Live server subprocess testing with
subprocess_async_clientandsubprocess_sync_client - Integration with
pytest-databases(see../pytest-databases/SKILL.md) andpolyfactory(see../polyfactory/SKILL.md) - Autowire discovery and cache isolation (see
../litestar-autowire/references/testing.md)
For JS-side testing (Vitest, Testing Library, Playwright), use the upstream Vitest docs and Litestar's own JS examples. Out of scope here.
Code Style Rules
- PEP 604 unions:
T | None, neverOptional[T] - Test modules MAY use
from __future__ import annotations— they are pure consumer code. - Function-based tests (not class-based)
- One assertion concern per test
- Async Litestar tests use
@pytest.mark.anyioby default; do not mix AnyIO andpytest-asyncioauto modes. - Prefer
AsyncTestClientfor new code;TestClientonly for legacy / sync-only flows. - Always enter test clients as context managers (
async with AsyncTestClient(...)/with TestClient(...)) — implicit lifespan startup without a context manager emitsDeprecationWarningand is removed in Litestar 3.0.
Quick Reference
TestClient vs AsyncTestClient
| Client | Base Class | Context Manager | Session Helpers | WebSocket Connect | |
|---|---|---|---|---|---|
AsyncTestClient | httpx.AsyncClient, BaseTestClient | async with AsyncTestClient(app=app) as client: | await client.set_session_data(...) / await client.get_session_data() | with await client.websocket_connect("/ws") as ws: | |
TestClient | httpx.Client, BaseTestClient | with TestClient(app=app) as client: | client.set_session_data(...) / client.get_session_data() | with client.websocket_connect("/ws") as ws: |
Both clients accept the same constructor parameters:
Both set follow_redirects=True and headers={"user-agent": "testclient"} by default. When testing template responses, TestClientTransport populates response.template and response.context on the returned httpx.Response.
create_test_client and create_async_test_client
For isolated route handler, controller, or router tests without bootstrapping the full application factory, use create_async_test_client(route_handlers=..., **litestar_and_client_kwargs) (or create_test_client for sync tests). Both build a Litestar instance and return a configured test client.
anyio vs pytest-asyncio Setup
Prefer @pytest.mark.anyio because Litestar's internal concurrency model is built on AnyIO. Do not mix @pytest.mark.anyio and @pytest.mark.asyncio in the same test module.
App + Lifespan Fixture
async with AsyncTestClient(...) enters LifeSpanHandler, firing on_startup / on_shutdown hooks and plugin lifespan context managers (Vite, SAQ, SQLAlchemy, Channels, etc.). Without the context manager, implicit startup emits a DeprecationWarning and shutdown hooks never run.
Mocking Guards & Overriding DI Dependencies (Match Your Stack)
Guards are functions of (connection: ASGIConnection, route_handler: BaseRouteHandler) -> None | Awaitable[None]. Test the real guard with fake identity or authorization providers, or unit-test the guard directly with RequestFactory. Build a fresh app with replacement providers; Litestar has no mutable app.dependency_overrides registry.
- Option A — Litestar Built-in DI (`Provide` + `NamedDependency`): Pass replacement
Provideentries tocreate_app(dependencies=...)orcreate_async_test_client(..., dependencies=...). Handler parameters resolved by name must useNamedDependency[T]. For synchronous test providers, always specifysync_to_thread=False(orTrue) to avoidLitestarWarning. - Option B — Dishka DI (`Provider` + `make_async_container`): Subclass
Providerin tests and pass the test provider afterLitestarProvider()and production providers inmake_async_container(LitestarProvider(), AppProvider(), FakeEmailProvider(mock_email))— later providers override earlier ones for matching return types. Route handlers usingFromDishka[T]must be decorated with@inject(or@inject_websocket, or registered on aDishkaRouter) before callingsetup_dishka(container=container, app=app). See Async Testing for fullFakeEmailProvideranddishka_clientfixture patterns.
Session Testing (set_session_data and get_session_data)
Pass the same session_config (ServerSideSessionConfig or CookieBackendConfig) to both middleware=[session_config.middleware] and session_config=session_config on the test client (omitting session_config on the client raises ImproperlyConfiguredException). On AsyncTestClient, await client.set_session_data(data) and await client.get_session_data() are async; on TestClient, they are sync.
WebSocket, SSE (ServerSentEvent), and ChannelsPlugin Testing
- WebSockets (`websocket_connect`): On
AsyncTestClient,websocket_connectisasync def(must be awaited), while the returnedWebSocketTestSessionis always a synchronous context manager (with await client.websocket_connect(...) as ws:) with synchronous methods (ws.send_json(...),ws.receive_json(...),ws.close(...)). Server-initiated close causesws.receive*()to raiselitestar.exceptions.WebSocketDisconnect. - SSE (`ServerSentEvent`): Stream events with
async with client.stream("GET", "/sse") as resp:and iterateresp.aiter_lines(). - `ChannelsPlugin`: Configure
ChannelsPlugin(backend=MemoryChannelsBackend(), channels=["alerts"], create_ws_route_handlers=True)and enterasync with create_async_test_client(plugins=[channels_plugin]) as client:. Publish viachannels_plugin.publish(data, channels=["alerts"])and consume viawebsocket_connect.
Unit Testing with RequestFactory & Live Subprocess Clients
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/litestar-testing/SKILL.md
Popularity
- Repository stars
- 15
- 7-day trend score
- 14
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/litestar-org/litestar-skills/litestar-testing)