第 13 章: FastAPI应用测试
本章概述
学习如何使用pytest为FastAPI应用编写单元测试。
13.1 pytest简介
pytest是Python的测试框架,简单易用:
安装
pip install pytest
pip install httpx # 用于测试API13.2 创建第一个测试
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_read_main():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"Hello": "World"}运行测试:
pytest13.3 使用pytest fixtures删除重复代码
import pytest
@pytest.fixture
def client():
from main import app
with TestClient(app) as c:
yield c
def test_read_main(client):
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"Hello": "World"}说明:fixture是pytest的概念,用于提供测试前的准备工作。
13.4 测试用户模块
def test_create_user(client):
response = client.post(
"/users/",
json={"username": "test", "password": "test123"}
)
assert response.status_code == 201
data = response.json()
assert data["username"] == "test"
def test_login(client):
# 先创建用户
client.post(
"/users/",
json={"username": "test", "password": "test123"}
)
# 登录
response = client.post(
"/token",
data={"username": "test", "password": "test123"}
)
assert response.status_code == 200
assert "access_token" in response.json()13.5 测试任务模块
def test_create_task(client):
# 先登录获取token
client.post(
"/users/",
json={"username": "test", "password": "test123"}
)
response = client.post(
"/token",
data={"username": "test", "password": "test123"}
)
token = response.json()["access_token"]
# 创建任务
response = client.post(
"/tasks/",
json={"name": "Test Task"},
headers={"Authorization": f"Bearer {token}"}
)
assert response.status_code == 201
def test_get_all_tasks(client):
# 登录并创建任务...
response = client.get(
"/tasks/",
headers={"Authorization": f"Bearer {token}"}
)
assert response.status_code == 200
assert isinstance(response.json(), list)13.6 测试数据库
使用独立的测试数据库:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from main import Base
# 测试数据库
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
@pytest.fixture
def db():
# 创建测试数据库表
Base.metadata.create_all(bind=engine)
db = TestingSessionLocal()
try:
yield db
finally:
db.close()
# 删除测试数据库表
Base.metadata.drop_all(bind=engine)13.7 事件循环(Event Loop)
FastAPI支持异步测试:
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_async_endpoint():
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.get("/")
assert response.status_code == 20013.8 测试覆盖率和报告
pip install pytest-cov
pytest --cov=app --cov-report=html这会生成HTML格式的测试覆盖率报告。
小结
在本章中,我们学习了: - ✅ 使用pytest编写测试 - ✅ 使用TestClient测试API - ✅ 使用fixtures管理测试依赖 - ✅ 测试用户认证 - ✅ 测试CRUD操作 - ✅ 使用测试数据库 - ✅ 异步测试 - ✅ 测试覆盖率报告
🎉 总结
恭喜!你已经完成了FastAPI的学习之路。现在你应该能够:
- ✅ 创建FastAPI应用
- ✅ 定义路由和参数
- ✅ 使用Pydantic验证数据
- ✅ 连接数据库
- ✅ 使用模板引擎
- ✅ 实现认证
- ✅ 编写测试
下一步学习建议
- 部署FastAPI应用:学习如何使用Docker、Nginx部署
- WebSocket:FastAPI支持WebSocket实时通信
- GraphQL:使用Strawberry或Ariadne集成GraphQL
- 后台任务:使用Celery或ARQ处理后台任务
- 微服务:将FastAPI应用拆分为微服务架构
推荐资源
- 官方文档:https://fastapi.tiangolo.com/
- GitHub:https://github.com/tiangolo/fastapi
- 示例项目:https://github.com/tiangolo/full-stack-fastapi-template
继续实践和探索,祝你在FastAPI的开发旅程中取得成功!🚀