前言
- 前面講解了通過 pytest 進行單元測試,是針對同步函數的:https://www.cnblogs.com/poloyy/p/15354901.html
- 但它無法再 pytest 中測試或運行任何異步函數
- 能夠在測試中使用異步函數可能很有用
- 例如,當異步查詢數據庫時,假設想要測試向 FastAPI 應用程序發送請求,然后驗證后端是否成功在數據庫中寫入了正確的數據,同時使用異步數據庫
FastAPI 代碼
from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"message": "Tomato"}
單元測試代碼
需要先安裝
pip install httpx pip install trio pip install anyio
測試代碼
import pytest from httpx import AsyncClient from .main import app @pytest.mark.anyio async def test_root(): async with AsyncClient(app=app, base_url="http://test") as ac: response = await ac.get("/") assert response.status_code == 200 assert response.json() == {"message": "Tomato"}
httpx
- 即使 FastAPI 應用程序使用普通 def 函數而不是 async def,它仍然是一個異步應用程序
- TestClient 在內部使用標准 pytest 在正常 def 測試函數中調用異步 FastAPI 應用程序做了一些魔術
- 但是當在異步函數中使用調用異步 FastAPI 應用程序時,這種魔法就不再起作用了
- 通過異步運行測試用例,不能再在測試函數中使用 TestClient,此時有一個不錯的替代方案,稱為 HTTPX
- HTTPX 是 Python 3 的 HTTP 客戶端,它允許像使用 TestClient 一樣查詢 FastAPI 應用程序
- HTTPX 的 API 和 requests 庫幾乎相同
- 重要的區別:用 HTTPX 不僅限於同步,還可以發出異步請求
@pytest.mark.anyio
告訴 pytest 這個測試函數應該異步調用
AsyncClient
- 通過使用 FastAPI app 創建一個 AsyncClient,並使用 await 向它發送異步請求
- 需要搭配 async/await 一起使用