pypi-fastapi

Description
FastAPI framework, high performance, easy to learn, fast to code, ready for production
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/pypi-fastapi@0.116.0

testing.md docs/

1
# Testing Support
2
3
FastAPI provides comprehensive testing capabilities through the TestClient class, which enables testing of FastAPI applications with full HTTP request simulation. The TestClient is built on top of HTTPX and provides a convenient interface for testing API endpoints without needing to run a live server.
4
5
## Capabilities
6
7
### TestClient Class
8
9
A test client for testing FastAPI applications with comprehensive HTTP request simulation capabilities.
10
11
```python { .api }
12
class TestClient:
13
def __init__(
14
self,
15
app: ASGIApp,
16
base_url: str = "http://testserver",
17
raise_server_exceptions: bool = True,
18
root_path: str = "",
19
backend: str = "asyncio",
20
backend_options: dict = None,
21
cookies: httpx.Cookies = None,
22
headers: dict = None,
23
follow_redirects: bool = False,
24
) -> None:
25
"""
26
Create a test client for a FastAPI application.
27
28
Parameters:
29
- app: The FastAPI application to test
30
- base_url: Base URL for requests (default: http://testserver)
31
- raise_server_exceptions: Whether to raise server exceptions during tests
32
- root_path: Root path for the application
33
- backend: Async backend to use (asyncio or trio)
34
- backend_options: Options for the async backend
35
- cookies: Default cookies for requests
36
- headers: Default headers for requests
37
- follow_redirects: Whether to automatically follow redirects
38
"""
39
```
40
41
### HTTP Methods
42
43
Standard HTTP methods for testing API endpoints with full request and response handling.
44
45
```python { .api }
46
def get(self, url: str, **kwargs) -> httpx.Response:
47
"""Send GET request to the specified URL."""
48
49
def post(self, url: str, **kwargs) -> httpx.Response:
50
"""Send POST request with optional data/json body."""
51
52
def put(self, url: str, **kwargs) -> httpx.Response:
53
"""Send PUT request with optional data/json body."""
54
55
def delete(self, url: str, **kwargs) -> httpx.Response:
56
"""Send DELETE request to the specified URL."""
57
58
def patch(self, url: str, **kwargs) -> httpx.Response:
59
"""Send PATCH request with optional data/json body."""
60
61
def head(self, url: str, **kwargs) -> httpx.Response:
62
"""Send HEAD request to the specified URL."""
63
64
def options(self, url: str, **kwargs) -> httpx.Response:
65
"""Send OPTIONS request to the specified URL."""
66
67
def request(
68
self,
69
method: str,
70
url: str,
71
**kwargs
72
) -> httpx.Response:
73
"""Send request with specified HTTP method."""
74
```
75
76
### Context Manager Support
77
78
TestClient supports context manager protocol for proper resource cleanup.
79
80
```python { .api }
81
def __enter__(self) -> TestClient:
82
"""Enter context manager."""
83
84
def __exit__(self, *args) -> None:
85
"""Exit context manager and cleanup resources."""
86
```
87
88
### WebSocket Testing
89
90
Support for testing WebSocket connections.
91
92
```python { .api }
93
def websocket_connect(
94
self,
95
url: str,
96
subprotocols: List[str] = None,
97
**kwargs
98
) -> WebSocketTestSession:
99
"""Create WebSocket connection for testing."""
100
```
101
102
## Usage Examples
103
104
### Basic API Testing
105
106
```python
107
from fastapi import FastAPI
108
from fastapi.testclient import TestClient
109
110
app = FastAPI()
111
112
@app.get("/items/{item_id}")
113
def read_item(item_id: int, q: str = None):
114
return {"item_id": item_id, "q": q}
115
116
@app.post("/items/")
117
def create_item(item: dict):
118
return item
119
120
# Create test client
121
client = TestClient(app)
122
123
def test_read_item():
124
response = client.get("/items/1?q=test")
125
assert response.status_code == 200
126
assert response.json() == {"item_id": 1, "q": "test"}
127
128
def test_create_item():
129
item_data = {"name": "Test Item", "price": 10.50}
130
response = client.post("/items/", json=item_data)
131
assert response.status_code == 200
132
assert response.json() == item_data
133
```
134
135
### Testing with Authentication
136
137
```python
138
from fastapi import FastAPI, Depends, HTTPException, status
139
from fastapi.security import HTTPBearer
140
from fastapi.testclient import TestClient
141
142
app = FastAPI()
143
security = HTTPBearer()
144
145
@app.get("/protected")
146
def protected_endpoint(token: str = Depends(security)):
147
if token.credentials != "valid-token":
148
raise HTTPException(status_code=401, detail="Invalid token")
149
return {"message": "Protected data"}
150
151
client = TestClient(app)
152
153
def test_protected_endpoint():
154
# Test without token
155
response = client.get("/protected")
156
assert response.status_code == 403
157
158
# Test with invalid token
159
response = client.get(
160
"/protected",
161
headers={"Authorization": "Bearer invalid-token"}
162
)
163
assert response.status_code == 401
164
165
# Test with valid token
166
response = client.get(
167
"/protected",
168
headers={"Authorization": "Bearer valid-token"}
169
)
170
assert response.status_code == 200
171
assert response.json() == {"message": "Protected data"}
172
```
173
174
### Testing File Uploads
175
176
```python
177
from fastapi import FastAPI, File, UploadFile
178
from fastapi.testclient import TestClient
179
import io
180
181
app = FastAPI()
182
183
@app.post("/upload/")
184
def upload_file(file: UploadFile = File(...)):
185
return {"filename": file.filename, "size": len(file.file.read())}
186
187
client = TestClient(app)
188
189
def test_file_upload():
190
test_file = io.BytesIO(b"test file content")
191
response = client.post(
192
"/upload/",
193
files={"file": ("test.txt", test_file, "text/plain")}
194
)
195
assert response.status_code == 200
196
data = response.json()
197
assert data["filename"] == "test.txt"
198
assert data["size"] > 0
199
```
200
201
### Testing with Context Manager
202
203
```python
204
from fastapi import FastAPI
205
from fastapi.testclient import TestClient
206
207
app = FastAPI()
208
209
@app.get("/")
210
def read_root():
211
return {"Hello": "World"}
212
213
def test_with_context_manager():
214
with TestClient(app) as client:
215
response = client.get("/")
216
assert response.status_code == 200
217
assert response.json() == {"Hello": "World"}
218
```
219
220
### WebSocket Testing
221
222
```python
223
from fastapi import FastAPI, WebSocket
224
from fastapi.testclient import TestClient
225
226
app = FastAPI()
227
228
@app.websocket("/ws")
229
async def websocket_endpoint(websocket: WebSocket):
230
await websocket.accept()
231
await websocket.send_text("Hello WebSocket!")
232
await websocket.close()
233
234
client = TestClient(app)
235
236
def test_websocket():
237
with client.websocket_connect("/ws") as websocket:
238
data = websocket.receive_text()
239
assert data == "Hello WebSocket!"
240
```
241
242
## Types
243
244
```python { .api }
245
from typing import Any, Dict, List, Optional, Union
246
import httpx
247
from starlette.types import ASGIApp
248
249
# Test client response type
250
TestResponse = httpx.Response
251
252
# WebSocket test session
253
class WebSocketTestSession:
254
def send_text(self, data: str) -> None: ...
255
def send_bytes(self, data: bytes) -> None: ...
256
def send_json(self, data: Any) -> None: ...
257
def receive_text(self) -> str: ...
258
def receive_bytes(self) -> bytes: ...
259
def receive_json(self) -> Any: ...
260
def close(self, code: int = 1000) -> None: ...
261
```