12

我正在测试一个 Flask 应用程序(Flask 0.9),特别是我有一个会话装置,我想以记录的方式运行,就像这样(据我了解):

from flask import Flask, session
app = Flask(__name__)

@app.route('/', methods=['POST'])
def m():
    logging.error(session) # expect {'x': 1}
    return ""

with app.test_request_context() as trc:
  with app.test_client() as c:
    with c.session_transaction() as sess:
      sess['x'] = 1
    c.post()

这按预期工作,输出如下所示:

ERROR:root:<SecureCookieSession {'x': 1}>

不幸的是,我遇到了一个未在端点函数中设置会话数据的意外结果,即输出如下所示:

ERROR:root:<SecureCookieSession {}>

仅当从我的单元测试框架运行时才会出现此问题。就目前而言,我无法用退化的情况重现这个问题,尽管我已经做出了相当大的努力,其中一些努力的要点在这里。重点是我已经包括在内itsdangerous,并且Google App Engine testbed期望其中之一可能是原因。

在我自己的系统上,我比gist走得更远,并且几乎完全复制了我的单元测试框架,试图隔离这一点。同样,我已经从我的测试框架中删除了越来越多的相关代码。就这一点而言,我无法想到可能影响结果的退化案例和我的精简框架之间的差异。我已经遍历了c.post()pdb 中的调用,试图找出这种恶意的原因,但还没有收集到任何有用的见解。

总而言之,对于问题可能出在哪里的一点指导或建议,我将不胜感激。什么可能会影响 Werkzeug 的环境,以至于session_transaction没有得到尊重?

4

4 回答 4

4

就我而言,我通过加载配置文件将 cookie 自动限制到特定域。通过即时更新配置,我能够在单元测试时让 cookie 工作。将SESSION_COOKIE_DOMAIN属性设置为None,所有域(即 localhost)都可以设置会话。

app.config.update(                                                     
    SESSION_COOKIE_DOMAIN = None                                                
)

您可能想要摆弄文档中配置处理下描述的配置设置。

于 2014-04-05T06:04:44.460 回答
1

我讨厌复活一个老问题,但我相信我已经找到了解决这个问题的办法。为了进行测试,请尝试将您的服务器名称设置为localhost

app.config['SERVER_NAME'] = 'localhost'

我最初使用的是 Brian 的 hack,但这为我解决了问题。

于 2016-01-13T18:20:24.343 回答
0

如果没有一个实际失败的测试用例,就很难说什么。我能想到的是,TestClient您使用的发出请求的实例与您用于设置会话的实例不同。例如,您可以通过以下方式使要点按预期失败:

with self.app.test_client() as c:
    with c.session_transaction() as sess:
        sess['d'] = 1
    self.client.post()

但由于这里的情况或要点并非如此,请去想一想。

于 2013-05-17T19:35:13.047 回答
0

这是我最终做的事情:

# Code that modifies the current `session`; we must be in a test context already.
headers = {}
with self.client.session_transaction():
    # Get the cookie that is sent to the browser to establish a connection
    # via a fake request.
    response = make_response()
    self.app.session_interface.save_session(self.app, session, response)
    headers['Cookie'] = response.headers.get('Set-Cookie', '')
self.client.post(..., headers=headers)  # also works for .get, .put, etc.
于 2015-02-20T21:52:46.407 回答