我正在使用Deferred Callback Pattern snippet在 Flask 中设置 cookie。 (当前使用 11.1,但尝试过 12.0,行为也没有变化。)
我已经添加了打印语句来确定,但可以通过其他方式(检查 cookie)确认当我的应用程序在 Gunicorn 或 Flask 的调试服务器中运行时回调会按预期运行。
在 pytest (3.0.5) 中运行时,我可以确认请求在测试中执行,因为命令输出经过测试检查并且匹配。
但是,虽然添加了回调,但它不会运行。 (通过 Print 语句和检查测试客户端的 cookie jar 进行确认。)
测试代码为:
def test_get_new_auth_happy_path_basic_auth_preloaded(monkeypatch, client):
'''
Test that, when a client requests a token, and that client already
has the 'basic auth' credentials preloaded with valid values, the
client response includes the cookie setting with the matching token.
'''
monkeypatch.setattr('powersvc.auth.get_public_key',
mock.Mock(return_value=SECRET))
monkeypatch.setattr('powersvc.auth.get_token', mock_get_token)
basic_auth = "Basic {user}".format(user=b64encode(
b"{username}:{password}".format(username=USERNAME,
password=PASSWORD)))
res = client.get("/v1.1/token", headers={
"Authorization": basic_auth,
})
assert res.status_code == 200
assert res.get_data() == str(TOKEN)
assert auth.TOKEN_HEADER in client.cookie_jar
前两个断言通过,第三个断言失败。
[编辑:上面的第三个测试是错误的,但是使用 --pdb 运行 pytest 我还可以看到 cookie 未设置:
(Pdb) print res.headers
Content-Type: text/html; charset=utf-8
Content-Length: 109
(Pdb)
感谢 Nick Frost 指出这一点。]
我尝试用两种不同的方式重写测试——使用 pytest-flask live_server 固定装置(当前在 pytest-flask 0.10.0 上),以及仅使用基本的 pytest,不使用任何 pytest-flask 固定装置——而且它们全部都以同样的方式失败:回调已添加,回调未执行,并且 cookie 相应地不存在。
同样,代码在正常执行时有效,只有在通过 pytest 执行时才有效。
为了完整起见,这里是添加回调的/v1.1/token 函数。 (除了日志语句之外,回调代码与上面的代码片段相同。):
def get_new_auth():
'''
Attempt to get a new token with a username and password via Basic Auth
and put this new token in a cookie.
If we get a valid token, return its decrypted form.
If no valid token is possible, return None.
'''
LOGGER.debug('In get_new_auth.')
auth = flask.request.authorization
if auth:
token = get_token(auth.username, auth.password)
LOGGER.debug('Auth found. New token is {}'.format(token))
# Set a callback to ensure the token cookie gets set
@server.after_this_request
def add_token(response):
response.set_cookie(TOKEN_HEADER, token)
return str(decrypt_token(token))
else: # No basic auth in request
LOGGER.debug('No auth information available - demanding new auth')
return demand_authentication()
最佳答案
将您的代码与 Flask 片段代码一起使用,看起来确实已经设置了 cookie。但是,您的测试代码似乎有问题。
事实证明,client.cookie_jar 中的 'cookie_name'
不会告诉您 cookie 是否在 cookie jar 中。您可以直接检查 Set-Cookie
header 来查看 cookie 是否已设置:
assert 'Set-Cookie' in res.headers
assert res.headers['Set-Cookie'].startswith(auth.TOKEN_HEADER + '=')
或者,您可以使用 CookieJar直接检查 client
的 cookie jar 中是否有 token :
assert auth.TOKEN_HEADER in client.cookie_jar._cookies['localhost.local']['/']
编辑:您还可以创建 flask.Response
对象并返回该对象,而不是通过回调:
token = get_token(auth.username, auth.password)
LOGGER.debug('Auth found. New token is {}'.format(token))
res = Response(str(decrypt_token(token)))
res.set_cookie(TOKEN_HEADER, token)
return res
关于python - Flask 回调未通过 pytest 运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42519496/