Jupyter AI

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

📅 发表日期: 2024年8月18日

分类: 🚀Python FastAPI 入门

👁️阅读: --

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

1. FastAPI应用概述

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

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,可以通过以下命令进行安装:

pip install pytest httpx

2.2. 编写测试用例

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

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 文件的目录,然后运行:

pytest test_main.py

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

================================= test session starts =================================
collected 2 items

test_main.py ..                                                                  [100%]

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

4. 进一步扩展

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

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

4.1. 异常处理示例

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

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. 边界情况示例

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

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的功能来简化测试过程。希望大家能继续关注!

🚀Python FastAPI 入门 (滚动鼠标查看)