Lewati ke isi

Pengujian

Sisi klien pengujian memungkinkan Anda menggunakan perpustakaan httpx untuk membuat permintaan terhadap aplikasi ASGI Anda.

Dari pemula. Tanggapan impor HTMLResponse
Dari starlette.testclient impor TestClient


Async aplikasi def (lingkup, menerima, mengirim):
    Tegaskan lingkup ['tipe'] = = 'http'
    Tanggapan = Respon HTML ('<html><body>Halo, dunia!</body></html>')
    Menunggu tanggapan (lingkup, menerima, mengirim)


Uji coba _ aplikasi ():
    Klien = TestClient (aplikasi)
    Tanggapan = klien. Dapatkan ('/')
    Tegaskan tanggapan. status _ code = = 200

Antarmuka yang diekspos oleh sisi klien tes sama dengan sesi httpx lainnya. Secara khusus, doa yang membuat permintaan hanyalah panggilan fungsi standar, bukan objek yang dapat ditinggali.

Anda dapat menggunakan apa saja httpx API standar, seperti otentikasi, penanganan cookie sesi, atau pengunggahan file.

Misalnya, untuk mengatur header di TestClient, Anda dapat melakukan hal berikut:

Klien = TestClient (aplikasi)

# Atur header pada klien untuk permintaan di masa mendatang
Client.header = {"Authorization": "..."}
Tanggapan = klien. Dapatkan ("/")

# Atur header untuk setiap permintaan secara terpisah
Tanggapan = klien. Dapatkan ("/," header ={"Authorization": "..."})

Misalnya, menggunakan TestClient untuk mengirim file:

Klien = TestClient (aplikasi)

# Kirim satu file
Dengan pembukaan ("example.txt," "rb") sebagai f:
    Response = client.post ("/ form," berkas ={"file": f})

# Kirim beberapa file
Dengan pembukaan ("example.txt," "rb") sebagai f1:
    Dengan pembukaan ("contoh," "rb") sebagai f2:
        Berkas = {"file1": f1, "file2": ("filename", f2, "image/png")}
        Response = client.post ("/ form," file = file)

Untuk informasi lebih lanjut, Anda dapat melihat dokumentasi httpx.

Secara default,TestClient melemparkan pengecualian yang terjadi dalam aplikasi Anda. Kadang-kadang, Anda mungkin ingin menguji konten respons kesalahan 500 daripada membiarkan sisi klien membuang pengecualian server. Dalam hal ini, Anda harus menggunakan client = TestClient(app, raise_server_exceptions=False).

Perhatian

Jika Anda ingin TestClient menjalankan pawang lifespan, Anda harus menggunakan TestClient sebagai konteks manager.It akan Tidak dipicu ketika TestClient instantiated.You dapat mempelajari lebih lanjut tentang hal itu. di sini.

Pilih backend asinkron

TestClient menerima argumen backend(string) dan backend_options(kamus). Opsi ini diteruskan ke anyio.start_blocking_portal(). Lihat dokumentasi anyio untuk informasi lebih lanjut tentang opsi backend yang dapat diterima. Secara default,asyncio dan opsi default digunakan.

Maaf, arti "Trio" dan "backend="trio"" dalam teks aslinya tidak jelas dan tidak dapat diterjemahkan secara akurat. Jika Anda dapat memberikan informasi lebih lanjut tentang kedua simbol ini, saya akan mencoba yang terbaik untuk memberi Anda terjemahan yang lebih akurat.

Tes pasti _ app ()
    Dengan TestClient (aplikasi, backend = "trio") sebagai klien:
       ...

Untuk menjalankan asyncio dengan uvloop, lewati backend_options={"use_uvloop": True}. Sebagai contoh:

Tes pasti _ app ()
    Dengan TestClient (aplikasi, backend _ options ={"use_uvloop": True}) sebagai klien:
       ...

Menguji Sesi WebSocket

Anda juga dapat menguji sesi WebSocket menggunakan sisi klien tes.

httpx Pustaka akan digunakan untuk membuat jabat tangan awal, yang berarti Anda dapat menggunakan opsi otentikasi yang sama dan header tambahan antara tes HTTP dan WebSocket.

Dari starlette.testclient impor TestClient
Dari starlette.websockets mengimpor WebSockets


Async aplikasi def (lingkup, menerima, mengirim):
    Tegaskan lingkup ['tipe'] = = 'websockets'
    WebSocket = WebSocket (lingkup, terima = terima, kirim = kirim)
    Tunggu websocket.terima ()
    Tunggu websocket. kirim _ teks ('Halo, dunia!')
    Tunggu websocket.close ()


Uji coba _ aplikasi ():
    Klien = TestClient (aplikasi)
    Dengan klien.websocket _ connect ('/') sebagai websocket:
        Data = websocket.accept _ text ()
        Tegaskan data = = 'Halo, dunia!'

Operasi pada sesi adalah panggilan fungsi standar, bukan objek goyah.

Penting untuk menggunakan sesi dalam blok with yang dikelola konteks. Ini memastikan bahwa utas latar belakang tempat aplikasi ASGI berada di akhiri dengan benar, dan bahwa setiap pengecualian yang terjadi dalam aplikasi selalu diangkat oleh pihak klien pengujian.

Siapkan sesi tes

  • .websocket_connect(url, subprotocols=None, **options)- mengambil set parameter yang sama dengan httpx.get().

Jika aplikasi tidak menerima koneksi WebSocket,starlette.websockets.WebSocketDisconnect dapat dilemparkan.

websocket_connect() harus digunakan sebagaimanajer konteks (dalam blok with).

!!! Perhatikan bahwa parameter params tidak didukung oleh websocket_connect. Jika Anda perlu melewati parameter kueri, hardcoding langsung di URL.

```python
with client.websocket_connect('/path?foo=bar') as websocket:
    ...
```

kirim data

  • .send_text(data) - Kirim teks yang diberikan ke aplikasi.
  • .send_bytes(data) - Kirim byte yang diberikan ke aplikasi.
  • .send_json(data, mode="text")- Kirim data yang diberikan ke aplikasi. Gunakan mode="binary" untuk mengirim JSON melalui bingkai data biner.

menerima data

  • .receive_text() Tunggu teks masuk yang di kirim oleh aplikasi dan kembalikan.
  • .receive_bytes() - Tunggu string byte masuk yang di kirim oleh aplikasi dan kembalikan.
  • .receive_json(mode="text")- Menunggu data JSON masuk yang di kirim oleh aplikasi dan pengembalian. Menerima JSON melalui bingkai data biner menggunakan mode="binary".

Teks "Dapat meningkatkan starlette.websockets.WebSocketDisconnect." tampaknya tidak sesuai dengan ekspresi semantik konvensional, sehingga sulit untuk membuat terjemahan bahasa Mandarin yang akurat. Jika Anda memiliki lebih banyak informasi kontekstual atau mengkonfirmasi keakuratan konten teks, saya akan mencoba yang terbaik untuk memberi Anda terjemahan yang lebih memuaskan. Saat ini, terjemahan literal hanya dapat diterjemahkan sebagai: "Dapat meningkatkan starlette.websockets.WebSocketDisconnect." Tetapi terjemahan ini mungkin tidak praktis.

Tutup koneksi

  • .close(code=1000) - Lakukan operasi jarak dekat sisi klien pada koneksi WebSocket.

pengujian asinkron

Terkadang Anda ingin melakukan operasi asinkron di luar aplikasi Anda. Misalnya, Anda mungkin ingin memeriksa status database Anda setelah menggunakan aplikasi Anda menggunakan sisi / infrastruktur klien basis data asinkron yang ada.

Untuk kasus ini, menggunakan TestClient sulit karena menciptakan loop peristiwa sendiri, dan sumber daya asinkron, seperti koneksi database, sering tidak dibagi antara loop peristiwa. Cara termudah untuk memecahkan masalah ini adalah dengan membuat seluruh tes Anda asinkron dan menggunakan sisi klien asinkron seperti Httpx. AsyncClient.

Berikut adalah contoh tes tersebut:

AsyncClient impor dari htpx
Starlette.application diimpor dari Starlette
Dari starlette. rute impor routing
Dari bintang. permintaan permintaan impor
Dari pemula. Tanggapan impor PlainTextResponse


Silakan halo (permintaan: Permintaan) - > PlainTextResponse:
    Mengembalikan PlainTextResponse ("Halo Dunia!")


Aplikasi = Starlette (rute = [Rute ("/," halo) ])


# jika Anda menggunakan pytest, Anda harus menambahkan penanda async seperti:
# @ pytest.mark.anyio # menggunakan https://github.com/agronholm/anyio
# atau install dan konfigurasi pytest-asyncio (https://github.com/pytest-dev/pytest-asyncio)
Async def test _ app () - > Tidak ada:
    # catatan: Anda_harus_mengatur `base_url` untuk URL relatif seperti "/" untuk bekerja
    Sinkronisasi dengan AsyncClient (app = app, base _ url = "http: / / testserver") sebagai klien:
        R = menunggu klien. Dapatkan ("/")
        Tegaskan r. status _ code = = 200
        Tegaskan r.text = = "Halo Dunia!"