31 编写测试之编写单元测试

在上一篇文章中,我们讨论了如何使用异步操作与数据库进行交互。在本篇中,我们将专注于如何为我们的FastAPI应用编写单元测试。单元测试是验证我们应用程序单个组件是否按预期工作的重要步骤。在编写单元测试时,我们通常使用unittest模块或第三方测试框架pytest。在这篇文章中,我们将重点介绍如何使用pytest编写简单的单元测试。

1. FastAPI应用概述

在开始之前,我们先回顾一下我们在上一篇文章中创建的FastAPI应用。假设我们有一个简单的用户API,能进行CRUD操作。我们的应用包含一个用户模型和相应的路由:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List

app = FastAPI()

class User(BaseModel):
id: int
name: str
email: str

# 模拟数据库
fake_users_db = []

@app.post("/users/", response_model=User)
async def create_user(user: User):
fake_users_db.append(user)
return user

@app.get("/users/", response_model=List[User])
async def read_users():
return fake_users_db

这个简单的应用可以创建和读取用户。接下来,我们将为这些功能编写相应的单元测试。

2. 单元测试的基本结构

单元测试通常分为三个阶段:

  1. 准备阶段:设置测试所需的数据和环境。
  2. 执行阶段:执行被测试的模块或函数。
  3. 断言阶段:验证结果是否符合预期。

2.1. 安装 pytest

如果你还没有安装pytest,可以通过以下命令进行安装:

1
pip install pytest httpx

2.2. 编写测试用例

我们将在新的文件中创建测试用例,例如:test_main.py。下面是为我们的用户API编写测试的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import pytest
from fastapi.testclient import TestClient
from main import app, User

client = TestClient(app)

def test_create_user():
user_data = {"id": 1, "name": "Alice", "email": "alice@example.com"}
response = client.post("/users/", json=user_data)

assert response.status_code == 200
assert response.json() == user_data

def test_read_users():
response = client.get("/users/")

assert response.status_code == 200
assert response.json() == [{"id": 1, "name": "Alice", "email": "alice@example.com"}]

在上面的例子中:

  • 我们使用 TestClient 来模拟 HTTP 请求。
  • test_create_user 测试了创建用户的功能。
  • test_read_users 测试了获取用户列表的功能。

3. 运行测试

要运行测试,只需在终端中导航到包含 test_main.py 文件的目录,然后运行:

1
pytest test_main.py

如果一切正常,你应该会看到类似以下的输出:

1
2
3
4
5
6
================================= test session starts =================================
collected 2 items

test_main.py .. [100%]

================================== 2 passed in 0.03s ==================================

4. 进一步扩展

在真实的应用开发中,通常还需要:

  • 处理异常:测试在特定条件下是否合理抛出异常。
  • 边界情况:测试利用边界条件来加固你的测试(比如空输入等)。
  • 数据库测试:在需要连接数据库的情况下,考虑如何模拟数据库或使用测试数据库。

4.1. 异常处理示例

下面的示例展示了如何测试错误处理:

1
2
3
4
5
def test_create_user_without_email():
user_data = {"id": 2, "name": "Bob"}
response = client.post("/users/", json=user_data)

assert response.status_code == 422 # Unprocessable Entity

4.2. 边界情况示例

你也可以测试使用不合理的输入:

1
2
3
4
5
def test_create_user_with_invalid_data():
user_data = {"id": "not-a-number", "name": "Charlie", "email": "charlie@example.com"}
response = client.post("/users/", json=user_data)

assert response.status_code == 422 # Unprocessable Entity

5. 小结

在这一章中,我们学习了如何为我们的FastAPI应用编写单元测试,包括创建、读取用户的API。单元测试不只是确保代码的质量,更是确保我们在进行变更时不会引入新的错误。

在下一篇文章中,我们将进一步探讨如何使用 pytest 进行更深入的测试,涉及到更复杂的用例以及如何通过pytest的功能来简化测试过程。希望大家能继续关注!

31 编写测试之编写单元测试

https://zglg.work/python-fastapi-zero/31/

作者

IT教程网(郭震)

发布于

2024-08-17

更新于

2024-08-18

许可协议

分享转发

交流

更多教程加公众号

更多教程加公众号

加入星球获取PDF

加入星球获取PDF

打卡评论