bigywater.tech
Flask · 157

测试文件上传

Flask 的上传接口怎么写测试?文件怎么构造?临时目录怎么处理?哪些边界值得测?这篇用一组真实运行的 pytest 用例把写法与结果逐项列出。

10 passed
本篇真实运行的上传测试数
tmp_path
pytest 提供的自动清理的临时目录,用作上传目录
seek(0)
复用 BytesIO 前必须做的事,否则只会读到剩下的字节

一组真实运行的上传测试

实测 · 本机执行输出
  test_single_file RESULT single 201 {'ctype': 'text/plain', 'field': 't1', 'original': 'a.txt', 'saved': '653ab3cb10d346b186307e726056bc6f.txt', 'size': 5}
  PASSED
  test_content_type_is_multipart_by_default RESULT auto-multipart 201 {'ctype': 'image/png', 'field': None, 'original': 'b.png', 'saved': '4291ea9ffdff411bb2080c1742544155.png', 'size': 1}
  PASSED
  test_declared_mimetype RESULT mimetype image/png
  PASSED
  test_no_file RESULT nofile 400 {'error': 'no file'}
  PASSED
  test_empty_filename RESULT emptyname 400 {'error': 'no file'}
  PASSED
  test_multi RESULT multi {'names': ['1.txt', '2.txt'], 'sizes': [1, 2]}
  PASSED
  test_too_large RESULT toolarge 413
  PASSED
  test_real_file_from_disk RESULT disk 201 30
  PASSED
  test_stream_position_matters RESULT position 3
  PASSED
  test_original_name_sanitized_on_disk RESULT name '../../evil name.txt' .txt ['.txt']
  PASSED
  ============================== 10 passed in 0.03s ==============================

上一篇:测试 Session;下一篇:测试异常处理器。

上传视图是一个简化版(保存到 UPLOAD_DIR、用 uuid 命名),类型校验见第 126 篇。

分步演示

测试文件上传
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动。pytest 9.1.1
    • 没有验证:分块上传与超大文件的流式处理、Flask-WTF 的 FileField 与 FileAllowed(第 73 篇)、并发上传、真实浏览器的 multipart 边界差异、文件存对象存储时的 mock 方式
    京ICP备2026067502号-1京公网安备11010502063487号