如何在pytest中定义含不定数量JSON项的响应预期体?
问题:如何在Python API测试中校验数量未知的响应JSON?
我刚开始学习使用Python测试API,还请包涵。我想测试一个从数据库返回所有用户的接口,预期响应体如下:
[ { "_id": "63811d56f6bea6b0dcb35342", "email": "jan_kowalski@poczta.com", "email_confirmed": "False", "is_active": true, "password": "12345", "secret": "hdoofdgxksesdjvfrzsfedgqzouqnxyk", "first_name": "Jan", "last_name": "Kowalski", "city": "Krakow", "postal_code": "97-406", "address": "ul. NMP 6" }, { "_id": "63811d6ef6bea6b0dcb35343", "email": "adam_kowalski@poczta.com", "email_confirmed": "False", "is_active": true, "password": "12345", "secret": "vxnktmnsuflvloduewglwdtrgplccqoe", "first_name": "Jan", "last_name": "Kowalski", "city": "Krakow", "postal_code": "97-406", "address": "ul. NMP 6" } ]
我的测试代码如下:
from app import main def test_get_all_users(test_app): response = test_app.get("/user/all") assert response.status_code == 200
我还需要添加响应JSON的正确性校验,比如assert response.json() == {*my json*},但不知道如何设置该断言以处理数量未知的JSON项?
解决方案
方法1:校验每个用户的结构与关键字段
如果用户数量不确定,但每个用户的字段结构固定,可以遍历响应列表,逐一检查必填字段、字段类型和关键内容的合法性。
示例代码:
def test_get_all_users(test_app): response = test_app.get("/user/all") assert response.status_code == 200 users = response.json() # 确认返回结果是列表类型 assert isinstance(users, list) # 定义每个用户必须包含的字段 required_fields = ["_id", "email", "email_confirmed", "is_active", "first_name", "last_name"] for user in users: # 检查必填字段是否存在 for field in required_fields: assert field in user # 校验字段类型与内容合法性 assert isinstance(user["_id"], str) assert isinstance(user["email"], str) assert user["email"].endswith("@poczta.com") # 验证邮箱后缀格式 assert isinstance(user["is_active"], bool) assert user["email_confirmed"] in ["True", "False"] # 确认值在合法范围内
方法2:用Schema校验库规范验证(以Pydantic为例)
如果需要更严谨的结构校验,可以用Pydantic定义用户数据模型,自动验证返回数据是否符合结构要求。
首先安装依赖:pip install pydantic
示例代码:
from pydantic import BaseModel, EmailStr from typing import List # 定义用户数据模型,自动校验字段类型与格式 class User(BaseModel): _id: str email: EmailStr email_confirmed: str is_active: bool password: str secret: str first_name: str last_name: str city: str postal_code: str address: str def test_get_all_users(test_app): response = test_app.get("/user/all") assert response.status_code == 200 users = response.json() # 用模型验证所有用户数据,不符合则抛出异常 try: [User(**user) for user in users] except Exception as e: assert False, f"响应数据不符合预期结构: {str(e)}"
方法3:控制测试环境数据量(固定校验)
如果测试数据库是独立的,可以在测试前预设固定数量的测试用户,直接校验返回列表的长度和具体内容。
示例代码:
def setup_test_users(): # 清空测试用户表,插入预设的测试数据(需根据你的数据库操作逻辑实现) test_user1 = { "_id": "63811d56f6bea6b0dcb35342", "email": "jan_kowalski@poczta.com", "email_confirmed": "False", "is_active": True, "password": "12345", "secret": "hdoofdgxksesdjvfrzsfedgqzouqnxyk", "first_name": "Jan", "last_name": "Kowalski", "city": "Krakow", "postal_code": "97-406", "address": "ul. NMP 6" } test_user2 = { "_id": "63811d6ef6bea6b0dcb35343", "email": "adam_kowalski@poczta.com", "email_confirmed": "False", "is_active": True, "password": "12345", "secret": "vxnktmnsuflvloduewglwdtrgplccqoe", "first_name": "Jan", "last_name": "Kowalski", "city": "Krakow", "postal_code": "97-406", "address": "ul. NMP 6" } # 插入数据库的逻辑... def test_get_all_users(test_app): setup_test_users() # 初始化测试数据 response = test_app.get("/user/all") assert response.status_code == 200 users = response.json() # 校验返回数量和关键内容 assert len(users) == 2 user_emails = [user["email"] for user in users] assert "jan_kowalski@poczta.com" in user_emails assert "adam_kowalski@poczta.com" in user_emails
内容的提问来源于stack exchange,提问作者folwarczyk
相关产品推荐
相关产品推荐

