2017-02-28 50 views
1

运行我使用的是Deferred Callback Pattern snippet设置在瓶的cookie。 (目前使用11.1,但尝试12.0也没有改变行为。)瓶回调不会通过pytest

我已经添加了打印语句是肯定的,但可以通过其他方式确认(检查cookie)回调得到按预期运行时,我的应用程序运行在gunicorn或Flask的调试服务器上。

当pytest(3.0.5)上运行的,我可以证实,该请求在测试,因为该命令输出由测试和火柴检查执行。

但是,虽然回调是增加了它不是运行。 (两者通过打印语句和检查测试客户端的cookie罐确认)

测试代码是:

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 

前两个断言通,并且第三失败。

[编辑:上面的第三个测试是错误的,但运行pytest与--pdb我还可以看到,该cookie不会设置:

(Pdb) print res.headers 
Content-Type: text/html; charset=utf-8 
Content-Length: 109 


(Pdb) 

感谢尼克·弗罗斯特指出这。]

我试着重写测试两种不同的方式 - 使用pytest-flask live_server夹具(目前在pytest-flask 0.10.0上),并且只使用基本的pytest而不使用pytest瓶夹具 - 并且它们都以相同的方式失败:添加回调,未执行回调,a nd相应地不在那里。

同样,代码正常执行时工作,只有当不经由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() 

回答

0

哎呀。更多交互式调查发现问题:

延迟回调片段使用@app。after_request修饰符 - 但 'app'变量不是指我在pytest夹具中使用的工厂生成的应用程序。

Ouch。

1

使用与瓶代码段代码,它确实看起来像饼干被设定。但是,您的测试代码看起来有问题。原来,'cookie_name' in client.cookie_jar不会告诉你cookie是否在饼干罐中。您可以改为直接检查Set-Cookie头,查看cookie是否被设置:

assert 'Set-Cookie' in res.headers 
assert res.headers['Set-Cookie'].startswith(auth.TOKEN_HEADER + '=') 

或者,你可以直接使用CookieJar内部检查client是否在其饼干罐令牌:

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 
+0

你是对的,测试被打破。 (我发现昨天晚上我发布后。)但是(因为我也验证了回调没有通过打印语句运行),该cookie没有被设置: (Pdb)打印res.headers 内容类型:text/html; charset = utf-8 内容长度:109 (Pdb) –

+0

您可以完全避免回调,请参阅上面的编辑方式以仅返回响应 –