bigywater.tech
Flask · 152

test_request_context()

什么时候该用 test_request_context 而不是 test_client?进入 with 之后哪些钩子执行了?url_for 在测试里为什么有时会报错?这篇逐项验证。

不执行钩子
进入 with 之后 before_request 等钩子都没有执行
SERVER_NAME
只有应用上下文时生成外部 URL 必须配置的项
teardown
退出 with 时才执行

测试读取 request 的函数

实测 · 本机执行输出
   POST /items/5 q=hello ua=unit-test

上一篇:Flask Test Client;下一篇:test_client() 与真实 HTTP 请求差异。

钩子与 teardown

实测 · 本机执行输出
  with 里面,EV = [] | g.pre = None
  退出 with 之后,EV = ['teardown_request', 'teardown_appcontext']
  手动调用 app.preprocess_request() 后 EV = ['before_request'] | g.pre = set by before_request | 返回值 None

full_dispatch_request

实测 · 本机执行输出
  响应: 200 {'i': 7} | 钩子顺序(退出前): ['before_request', 'after_request']
  退出之后: ['before_request', 'after_request', 'teardown_request', 'teardown_appcontext']

url_for 与上下文

实测 · 本机执行输出
  没有任何上下文时 url_for → Working outside of application context.
  test_request_context 里 url_for("item", i=3) → /items/3 | _external=True → http://localhost/items/3
  base_url='https://shop.example.test:8443' 时 _external → https://shop.example.test:8443/items/3
  只有 app_context、没配 SERVER_NAME 时 _external → Unable to build URLs outside an active request without 'SERVER_NAME' configured. Also conf
  配了 SERVER_NAME 后 app_context 里 _external → http://shop.example.test/items/3

两种上下文的区别

实测 · 本机执行输出
  app_context: has_app_context = True | has_request_context = False
  test_request_context: has_app_context = True | has_request_context = True

session 与 json

实测 · 本机执行输出
  request.get_json() → {'k': 'v'}
  session 可以读写,session["x"] = 1

分步演示

test_request_context()
本步的对象

    本文用到的工具与边界

    • 本机 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,数字每次运行会有小幅抖动
    • 没有验证:嵌套推入多个请求上下文时 g 与 session 的归属、test_request_context 与 app.test_cli_runner 的配合、before_request 返回响应时 preprocess_request 的短路行为、自定义 session 接口下的行为
    京ICP备2026067502号-1京公网安备11010502063487号