0%

FastAPI自学教程(47) - 测试机制

1. 基础用法

1
2
3
4
5
6
7
8
9
from fastapi.testclient import TestClient
from main import app

client = TestClient(app)

def test_read_root():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"message": "Hello World"}
  • 使用TestClient模拟HTTP请求,需安装httpx
  • 测试流程:
      graph TD
      A[初始化TestClient] --> B[发送模拟请求]
      B --> C[接收响应]
      C --> D{断言验证}
      D -->|通过| E[测试成功]
      D -->|失败| F[抛出异常]
  • 核心功能:
    • 支持所有HTTP方法(GET/POST/PUT等)
    • 自动处理请求/响应序列化
    • 与pytest完美集成

2. 带参数的端点测试

1
2
3
4
5
6
7
8
9
def test_read_item():
item_id = 42
response = client.get(f"/items/{item_id}")
assert response.status_code == 200
assert response.json() == {"item_id": item_id}

def test_invalid_item():
response = client.get("/items/foo")
assert response.status_code == 422 # 验证失败状态码
  • 路径参数验证:
    • 自动检测类型错误(如字符串传递到int参数)
    • 返回422状态码表示参数校验失败
  • 查询参数测试:
    1
    2
    3
    def test_query_param():
    response = client.get("/items/5?q=test")
    assert "q" in response.json()

3. 请求体与响应验证

1
2
3
4
5
def test_create_item():
test_data = {"name": "Test Item", "price": 9.99}
response = client.post("/items/", json=test_data)
assert response.status_code == 201
assert response.json()["name"] == test_data["name"]
  • 支持JSON请求体测试,自动验证Pydantic模型约束
  • 响应验证要点:
    • 状态码校验
    • 响应数据结构校验
    • 业务逻辑结果校验

4. 依赖项与数据库测试

1
2
3
4
5
6
7
8
from unittest.mock import Mock
from dependencies import get_db

app.dependency_overrides[get_db] = lambda: Mock()

def test_with_mocked_db():
response = client.get("/users/")
assert response.status_code == 200
  • 依赖注入覆盖:
    • 使用dependency_overrides替换真实依赖
    • 适合模拟数据库连接、认证服务等
  • 事务测试建议:
    • 每个测试用例使用独立事务
    • 测试后自动回滚变更

5. 高级测试技巧

5.1 参数化测试

1
2
3
4
5
6
7
8
9
10
import pytest

@pytest.mark.parametrize("item_id,status", [
(1, 200),
(999, 404),
("abc", 422)
])
def test_multiple_cases(item_id, status):
response = client.get(f"/items/{item_id}")
assert response.status_code == status

5.2 异常处理测试

1
2
3
4
def test_auth_failure():
response = client.get("/secure", headers={"Authorization": "invalid"})
assert response.status_code == 403
assert "detail" in response.json()

测试命令示例:

1
2
3
4
5
# 运行所有测试
pytest -v

# 运行单个测试模块
pytest tests/test_main.py