Flask中do_login会话值测试失败问题排查
Flask测试中do_login函数抛出KeyError的解决方法
问题根源
你测试代码里的会话对象搞混了:
do_login函数操作的是Flask全局的session(请求上下文里的session)- 而你在
c.session_transaction()里拿到的是测试客户端专属的会话对象
这俩是完全独立的,所以调用do_login后,修改的是请求上下文的session,不是客户端会话,自然断言的时候找不到curr_user键,抛出KeyError。
另外你嵌套了app.test_request_context()和self.client的with块,这完全没必要——测试客户端的with块会自动处理请求上下文,多套一层反而容易出问题。
解决方案
方案1:单独测试do_login函数本身的逻辑
如果只是想验证do_login能不能正确设置session,直接在请求上下文里测试就行,不用碰测试客户端的会话:
def test_do_login(self): """Does do_login function work?""" with app.test_request_context(): do_login(self.testuser) self.assertEqual(session["curr_user"], self.testuser.id)
方案2:测试客户端会话的登录状态(如果需要模拟用户登录后请求接口)
如果要测试用户登录后访问接口的场景,直接在session_transaction里操作会话,或者修改do_login支持传入session参数:
方法A:直接操作客户端会话
def test_client_login(self): """Test client session after login""" with self.client as c: with c.session_transaction() as session: session["curr_user"] = self.testuser.id # 之后用c.get()访问需要登录的接口,就能模拟已登录状态了 resp = c.get("/some/protected/route") # 断言响应内容,比如检查是否返回成功状态码 self.assertEqual(resp.status_code, 200)
方法B:修改do_login支持自定义session
把do_login改成可传入session参数,这样测试时可以传入客户端会话:
def do_login(user, session=None): """Log in user.""" # 优先用传入的session,没有则用全局session target_session = session or flask.session target_session["curr_user"] = user.id
然后测试代码改成:
def test_do_login_with_client_session(self): """Does do_login work with client session?""" with self.client as c: with c.session_transaction() as session: do_login(self.testuser, session=session) self.assertEqual(session["curr_user"], self.testuser.id)
这样就能保证do_login修改的是测试客户端的会话,断言自然不会报错。
内容的提问来源于stack exchange,提问作者Camden Tadhg
相关产品推荐
相关产品推荐

