- Python WebAPI開発用フレームワークFastAPIを使用して作成したAPIのテスト方法についてメモする。
大まかなテストコードの書き方
-
TestClient
をインポートする。 -
TestClient
を作成し、FastAPIに渡す。 -
test_
始まりの名前の関数を作成する (pytest
仕様)。 -
TestClient
オブジェクトを使用し、テスト用リクエストを記述する。 -
チェック内容の
assert
文を記述する。
事前準備
-
pytest
インストールpip install pytest
コード
テスト対象
-
main.py
- ユーザー情報の登録・取得を行うAPI
from fastapi import FastAPI, Header, HTTPException
from pydantic import BaseModel
# 正常トークン
correct_token = "correct_token"
# 模擬ユーザーデータ
dummy_user_db = {
"abcde12345": {"id": "abcde12345", "name": "Yamada", "email_address": "yamada@example.com"},
"fghij67890": {"id": "fghij67890", "name": "Tanaka", "email_address": "tanaka@example.com"},
}
app = FastAPI()
class User(BaseModel):
id: str
name: str
email_address: str
# ユーザー情報取得API
@app.get("/users/{user_id}", response_model=User)
async def get_user(user_id: str, token: str = Header(...)):
# トークン不正時
if token != correct_token:
raise HTTPException(
status_code=400, detail="token_verification_failed")
# ユーザー非存在時
if user_id not in dummy_user_db:
raise HTTPException(status_code=404, detail="user_not_found")
return dummy_user_db[user_id]
# ユーザー情報登録API
@app.post("/users/", response_model=User)
async def create_user(user: User, token: str = Header(...)):
# トークン不正時
if token != correct_token:
raise HTTPException(
status_code=400, detail="token_verification_failed")
# ユーザーID重複時
if user.id in dummy_user_db:
raise HTTPException(status_code=400, detail="user_id_duplicated")
dummy_user_db[user.id] = user
return user
テストコード
- 各APIの正常/異常系リクエスト時のレスポンスを検証する。
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
# ユーザー情報取得API 正常系テスト
def test_get_user_NR001():
response = client.get(
"/users/abcde12345", headers={"token": "correct_token"})
# レスポンス検証
# ステータスコード
assert response.status_code == 200
# レスポンスボディ
assert response.json() == {
"id": "abcde12345",
"name": "Yamada",
"email_address": "yamada@example.com",
}
# ユーザー情報取得API 異常系テスト
# トークン違い
def test_get_user_ABR001():
response = client.get("/users/abcde12345",
headers={"token": "dummy_token"})
assert response.status_code == 400
assert response.json() == {"detail": "token_verification_failed"}
# ユーザー情報取得API 異常系テスト
# 存在しないユーザー指定
def test_get_user_ABR002():
response = client.get(
"/users/hogefuga", headers={"token": "correct_token"})
assert response.status_code == 404
assert response.json() == {"detail": "user_not_found"}
# ユーザー情報登録API 正常系テスト
def test_create_user_NR001():
# 正常系リクエスト
# ヘッダーとボディは辞書型で渡す。
response = client.post(
"/users/",
headers={"Token": "correct_token"},
json={"id": "klmno12345", "name": "Kobayashi",
"email_address": "kobayashi@example.com"},
)
assert response.status_code == 200
assert response.json() == {
"id": "klmno12345",
"name": "Kobayashi",
"email_address": "kobayashi@example.com",
}
# ユーザー情報登録API 異常系テスト
# トークン違い
def test_create_user_ABR001():
response = client.post(
"/users/",
headers={"Token": "dummy_token"},
json={"id": "klmno12345", "name": "Kobayashi",
"email_address": "kobayashi@example.com"},
)
assert response.status_code == 400
assert response.json() == {"detail": "token_verification_failed"}
# ユーザー情報登録API 異常系テスト
# 登録済みユーザーID指定
def test_create_user_ABR002():
response = client.post(
"/users/",
headers={"Token": "correct_token"},
json={
"id": "abcde12345",
"name": "Kobayashi",
"email_address": "kobayashi@example.com"
},
)
assert response.status_code == 400
assert response.json() == {"detail": "user_id_duplicated"}
動作確認
pytest
================================================================ test session starts ================================================================
platform win32 -- Python 3.8.3, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: C:\Users\user\Documents\dev\vscode\ws_git\fastapi\test
plugins: anyio-3.2.1, cov-2.11.1
collected 6 items
test_main.py ...... [100%]
================================================================= 6 passed in 0.56s =================================================================