You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在pytest中编写multipart/form-data格式的文件上传接口测试?

刚好我之前做过类似的pytest测试照片上传接口的需求,给你分享下具体的实现步骤和踩坑点,应该能解决你提交photo_file的问题~

编写pytest测试照片上传POST接口的步骤

1. 先确认依赖

首先确保你已经安装了必要的包:

pip install pytest requests pillow pymongo

(pillow是用来生成临时测试图片的,如果你有现成的测试图也可以不用;pymongo用来验证MongoDB的数据存储)

2. 编写测试前置Fixtures

用pytest的fixture来统一管理测试资源,避免重复代码:

import pytest
import os
from PIL import Image
from pymongo import MongoClient
from your_project.models import Photo  # 替换成你项目中Photo类的导入路径

@pytest.fixture(scope="module")
def test_image():
    # 生成一个临时测试图片(或者直接用你本地的测试图片路径)
    temp_img_path = "temp_test_photo.jpg"
    # 创建一个100x100的红色测试图
    img = Image.new('RGB', (100, 100), color='crimson')
    img.save(temp_img_path)
    yield temp_img_path
    # 测试完成后清理临时文件
    if os.path.exists(temp_img_path):
        os.remove(temp_img_path)

@pytest.fixture(scope="module")
def test_mongo_db():
    # 连接测试专用的MongoDB实例!绝对不要用生产库!
    client = MongoClient("mongodb://localhost:27017/")
    test_db = client["test_photo_service"]
    yield test_db
    # 测试结束后清空测试集合,避免污染数据
    test_db.photos.delete_many({})
    client.close()

3. 核心测试用例实现

针对你的multipart/form-data上传接口,核心是正确构造files参数来传递图片文件,同时用data传递附加信息:

import requests

def test_photo_upload_success(test_image, test_mongo_db):
    # 替换成你的实际接口地址
    api_url = "http://localhost:5000/api/photos/upload"
    
    # 附加信息:完全按照Swagger定义的字段来传
    form_data = {
        "title": "海边日落测试图",
        "description": "这是一张用于pytest测试的照片",
        "category": "风景"
    }
    
    # 关键:构造文件参数,key必须和Swagger中定义的参数名一致(比如你说的photo_file)
    # 注意要用rb模式打开文件
    with open(test_image, "rb") as img_file:
        files = {
            "photo_file": (os.path.basename(test_image), img_file, "image/jpeg")
        }
        
        # 发送POST请求:data传表单字段,files传文件
        response = requests.post(api_url, data=form_data, files=files)
    
    # 第一步:断言响应状态码(一般创建成功是201)
    assert response.status_code == 201, f"上传失败,响应内容:{response.text}"
    
    # 第二步:解析响应数据,验证返回的字段
    response_json = response.json()
    assert "photo_id" in response_json, "响应未返回photo_id"
    uploaded_photo_id = response_json["photo_id"]
    
    # 第三步:验证MongoDB中是否正确存储了数据
    stored_photo = test_mongo_db.photos.find_one({"_id": uploaded_photo_id})
    assert stored_photo is not None, "照片未存入MongoDB"
    # 验证附加信息是否正确
    assert stored_photo["title"] == form_data["title"]
    assert stored_photo["description"] == form_data["description"]
    
    # 如果你的Photo类可以直接映射数据库文档,也可以用类来验证
    photo_instance = Photo(**stored_photo)
    assert photo_instance.category == form_data["category"]

4. 常见问题排查(针对你遇到的photo_file提交问题)

  • 参数key不匹配:一定要确保files中的key和Swagger里定义的上传参数名完全一致,比如Swagger里写的是photo_file就不能写成file或者image
  • 文件打开模式错误:必须用rb(二进制读)模式打开图片,用r模式会导致文件内容损坏
  • 接口需要认证:如果你的接口需要token或者权限验证,记得在请求头里加上:
    headers = {"Authorization": "Bearer your_test_token"}
    response = requests.post(api_url, data=form_data, files=files, headers=headers)
    
  • 测试数据库配置错误:确保你连接的是测试库,测试后一定要清理数据,避免影响后续测试

如果是用Flask/Django的测试客户端

如果你的服务是Flask或者Django,用框架自带的测试客户端写法会略有不同,以Flask为例:

from your_project.app import create_app

@pytest.fixture(scope="module")
def flask_client():
    app = create_app(config="testing")
    with app.test_client() as client:
        yield client

def test_flask_photo_upload(flask_client, test_image):
    with open(test_image, "rb") as img_file:
        # Flask测试客户端中,文件需要用元组格式:(文件名, 文件对象, 内容类型)
        data = {
            "title": "Flask测试图",
            "photo_file": (os.path.basename(test_image), img_file, "image/jpeg")
        }
        response = flask_client.post("/api/photos", data=data, content_type="multipart/form-data")
    
    assert response.status_code == 201
    # 后续断言逻辑和之前一致

内容的提问来源于stack exchange,提问作者urgent123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:35:06