Testing
Der Test-Client ermöglicht Ihnen die Verwendung httpx Requests werden an Ihre ASGI-Anwendung gesendet.
from starlette . responses import HTMLResponse (englisch)
von starlette . testclient import TestClient
async def app (scope , receive , send) :
assert scope ' type ' ] = ' http'.
Antwort = HTMLResponse ('<html><body>Hallo , Welt !</body></html>')
Erhalte Antworten (Senden , Empfangen , Senden)
def test _ app () (Beispiel) :
client = Testclient (Anwendung)
Antwort = client . get ('/')
assert response . status _ code = 200 Zeichen
Der Testclient ist mit der gleichen Schnittstelle konfrontiert wie jede andere httpx-Sitzung , insbesondere ist zu beachten , dass der Aufruf , der eine Anfrage stellt , nur ein Standardfunktionsaufruf ist und kein wartendes Objekt .
Sie können jede httpx-Standard - API verwenden , z . B . Authentifizierung , Verarbeitung von Sitzungs-Cookies oder Datei-Uploads .
Um beispielsweise Header auf TestClient festzulegen , können Sie dies wie folgt tun :
client = Testclient (Anwendung)
Legen Sie Header für zukünftige Anforderungen des Clients fest
Benutzer . headers = {"Authorization": "..."}
Antwort = client . get ("/" oder ")
# Setheaders für jeden Request getrennt
response = client . get ("/" , headers ={"Authorization": "..."}) [ Bearbeiten | Quelltext bearbeiten ]
Verwenden Sie beispielsweise TestClient , um Dateien zu senden :
client = Testclient (App) Bearbeiten
Ein einziges File senden
mit open (" beispiel.txt " , " rb ") as f :
antworten =client.post("/form " für files ={"file": f})
# Mehrere Dateien senden
with open (" beispiel.txt " , " rb ") as f1 :
mit open (" example.png " , " rb ") as f2 :
Dateien = {"file1": f1, "file2": ("filename", f2, "image/png")}
antworten =client.post(" Dateiendung " , files = files)
Für weitere Informationen können Sie sich die httpx-Dokumentation anschauen .
Standardmäßig löst TestClient alle Ausnahmen in Ihrer Anwendung aus und gelegentlich möchten Sie vielleicht den Inhalt einer 500 - Fehlerantwort testen , anstatt dem Client zu erlauben , eine Serverausnahme auszulösen In diesem Fall sollten Sie client = TestClient(app, raise_server_exceptions=False) verwenden .
!!! Achtung !
Wenn Sie die `TestClient` Der Lauf The `lifespan` Der Handler,
Sie müssen `TestClient` als Kontextmanager verwenden .
Wenn `TestClient` nicht installiert ist , können Sie mehr darüber erfahren
[hier](lifespan.md#running-lifespan-in-tests) hier .
Auswahl der Back-End
TestClient akzeptiert die Parameter backend(eine Zeichenfolge) und backend_options(ein Wörterbuch) Diese Optionen werden an anyio.start_blocking_portal() übergeben , weitere Informationen zu akzeptablen Backend-Optionen finden Sie in der anyio-Dokumentation standardmäßig unter Verwendung von asyncio und seinen Standardoptionen .
Es tut uns leid , dass die Bedeutung von "Trio" und "backend="trio"" im Originaltext nicht genau übersetzt werden kann Wenn Sie mehr Informationen über diese beiden Symbole zur Verfügung stellen können , werde ich versuchen , Ihnen eine genauere Übersetzung zu geben .
def test _ app () () (Übersetzung)
mit TestClient (app , backend = " trio ") als Client :
...
verwenden soll. uvloop Betrieb. asyncio übermittelt werden muss backend_options={"use_uvloop": True} Zum Beispiel:
def test _ app () () (Übersetzung)
mit TestClient (app, backend_options =){"use_uvloop": True}(als Kunde: )
...
Testen einer WebSocket-Sitzung
Sie können auch den Testclient zum Testen von WebSocket-Sitzungen verwenden .
httpx Die Bibliothek wird zum Erstellen eines anfänglichen Handshakes verwendet , was bedeutet , dass Sie die gleichen Authentifizierungsoptionen und andere Header zwischen HTTP - und WebSocket-Tests verwenden können .
von starlette . testclient import TestClient
from starlette . websockets import WebSockets (englisch)
async def app (scope, receive, send):
assert scope 'type']='websocket'.[Bearbeiten | Quelltext bearbeiten]
WebSocket = WebSocket (scope, receive = receive, send = send)
Websocket erstellen. accept ()
await websocket. send_text ('Hello, world gaward')[Quelltext bearbeiten]
websocket. close ()(schließen)
def test_app ()(Beispiel):
client = Testclient (App) Bearbeiten
mit client. websocket_connect ('/') as websocket:
Daten = websocket. receive_text ()
assert data =="Hallo Welt!"
Operationen in einer Sitzung sind Standardfunktionsaufrufe und keine wartbaren Objekte.
Die Verwendung von Sitzungen innerhalb eines kontextverwalteten with-Blocks ist wichtig, um sicherzustellen, dass der Hintergrundthread, in dem sich die ASGI-Anwendung befindet, ordnungsgemäß beendet wird und dass alle Ausnahmen, die innerhalb der Anwendung auftreten, immer vom Testclient ausgelöst werden.
Erstelle ein Testgespräch.
.websocket_connect(url, subprotocols=None, **options)-verwendet den gleichen Parametersatz wiehttpx.get().
Wenn die Anwendung keine WebSocket-Verbindungen akzeptiert, kann starlette.websockets.WebSocketDisconnect ausgelöst werden.
websocket_connect() muss als Kontext-Manager (im with-Block) verwendet werden.
!!! Achtung! params Parameter sind nicht betroffen websocket_connect Support Wenn Sie Abfrageparameter übergeben müssen, setzen Sie sie direkt in die URL fest.
```python
with client.websocket_connect('/path?foo=bar') as websocket:
...
```
Senden von Daten
.send_text(data)- Der Text wird an die Anwendung gesendet..send_bytes(data)- Die angegebenen Bytes werden an die Anwendung gesendet..send_json(data, mode="text")-Gibt Daten an eine Anwendung mitmode="binary", um JSON über binäre Datenrahmen zu senden.
Empfangen von Daten
.receive_text()- Warten Sie auf den eingehenden Text, der von der Anwendung gesendet wird, und geben Sie ihn zurück..receive_bytes()- Warten Sie auf die eingehende Bytefolge, die von der Anwendung gesendet wird, und geben Sie sie zurück..receive_json(mode="text")- Warten auf eingehende JSON-Daten , die von der Anwendung gesendet werden , und deren Rückgabe mithilfe vonmode="binary", um JSON über ein binäres Datenframe zu empfangen .
Der Text " May raise starlette.websockets.WebSocketDisconnect. " scheint weniger im Einklang mit dem regulären semantischen Ausdruck und schwierig , eine genaue chinesische Übersetzung zu machen Wenn Sie mehr kontextuelle Informationen haben oder die Richtigkeit des Textinhalts bestätigen , werde ich versuchen , Ihnen eine befriedigendere Übersetzung zu bieten derzeit nach wörtlicher Übersetzung , die nur übersetzt werden kann : " Vielleicht verbessern starlette.websockets.WebSocketDisconnect" , aber diese Übersetzung ist möglicherweise nicht ganz im Einklang mit der tatsächlichen Bedeutung .
Verbindungen schließen .
.close(code=1000)- Führt das Schließen der WebSocket-Verbindung durch den Client durch .
Ungleiche Proben .
Manchmal möchten Sie asynchrone Aktionen außerhalb der Anwendung ausführen , z . B . können Sie den Status einer Datenbank überprüfen , nachdem Sie Ihre Anwendung mit einem vorhandenen asynchronen Datenbankclient/- infrastruktur aufgerufen haben .
Für diese Fälle ist es schwierig ,TestClient zu verwenden , da es eine eigene Ereignisschleife erstellt und asynchrone Ressourcen (wie Datenbankverbindungen) oft nicht zwischen Ereignisschleifen geteilt werden können Der einfachste Weg , dieses Problem zu lösen , besteht darin , den gesamten Test asynchron zu machen und einen asynchronen Client wie httpx . AsyncClient zu verwenden .
Hier ist ein Beispiel für einen solchen Test :
from httpx import AsyncClient für Mac
von starlette . applications import Starlette
von starlette . routing import Route
from starlette . requests import Request (Eingabeaufforderung)
from starlette . responses import plainTextResponse (englisch)
def hello (request : Request) - > PlainTextResponse : Siehe auch :
Die Antwort lautet : " Hello World ! " .
Starlette (Route = [ Route ("/" , hallo) ]) [ Bearbeiten | Quelltext bearbeiten ]
# Wenn Sie Pytest verwenden , müssen Sie einen Async-Marker wie hinzufügen :
@anyio # usinghttps://github.com/agronholm/anyio
# or install and configure pytest-asyncio (https://github.com/pytest-dev/pytest-asyncio) installieren und konfigurieren
async def test _ app () - > None : keine :
#Zeichen: Du _muss_ Set `base_url` for relative urls like "/" zur Arbeit
async mit AsyncClient (app = app , base _ url = " http://testserver ") als Client :
r = await client . get ("/") (" wird angezeigt)
assert r . status _ code = 200 Zeichen
Text = = " Hallo Welt ! "