为什么使用 Flask 的 app.test_client() 而不是 requests.Session() 进行测试

Cha*_*bot 10 python flask python-3.x

Ifrequests.Session()可以处理 cookie 并且几乎可以完成所有app.test_client()操作。那为什么要使用app.test_client()

Cha*_*bot 6

经过一番挖掘,我想我找到了一个很好的理由来使用app.test_client()以及 Flask 提供的其他一些上下文管理器。

测试客户端

app.test_client()

使您能够通过其上下文管理器访问本地上下文 这在尝试访问_request_ctx_stack(请求上下文堆栈)上的变量时非常有用。例如requestsession上下文本地人。

一些扩展还将变量存储在_request_ctx_stack. 例如,flask_login存储current_userflask_stateless_auth存储current_stateless_user在请求上下文堆栈上。

from flask import request
from flask_stateless_auth import current_stateless_user

with app.test_client() as c:
  test_path = '/resource_for_authenticated_users'
  c.get(test_path)
  assert request.path == test_url
  assert flask.session is not None # You can also access the session context local from here
  assert current_stateless_user is not None
Run Code Online (Sandbox Code Playgroud)

如果在没有test_client()上下文管理器的情况下调用它,它将_request_ctx_stack在弹出后尝试访问请求本地上下文时抛出运行时错误。还有,current_stateless_user会回来None

应用上下文

app.app_context()

同样,您可以通过上下文管理器访问存储在应用程序上下文中的变量,app.app_context()例如:

from my_app.db import db # db connections are commonly stored on the `_app_ctx_stack`

with app.app_context():
  db.create_tables()
  assert db.session
  assert db.query.MyTable.all()
Run Code Online (Sandbox Code Playgroud)

您还可以访问应用程序上下文全局变量 (通常用于存储应用程序相关的全局变量,这些变量不会跨多个请求使用,如 session全局)

with app.app_context():
  assert g.my_global_app_var
Run Code Online (Sandbox Code Playgroud)

测试请求上下文

test_request_context()

然后你有app.test_request_context()上下文管理器,用于临时激活请求上下文。官方文档对此进行了最好的解释。

会话事务上下文

app.test_client().session_transaction()

最后,还有session_transaction()上下文管理器。这通常用于修改会话对象。这应该嵌套在app.test_client().

当该__exit__()方法被调用时,会话被安全地存储。

来自文档的示例:

with app.test_client() as c:
     with c.session_transaction() as sess:
         sess['a_key'] = 'a value'

    # once this is reached the session was stored
Run Code Online (Sandbox Code Playgroud)