Python 测试登录和身份验证?
我正在开发一个Flask应用程序,并使用Flask安全性进行用户身份验证(这反过来又使用Flask登录) 我有一条需要身份验证的路由,Python 测试登录和身份验证?,python,unit-testing,flask,flask-login,flask-security,Python,Unit Testing,Flask,Flask Login,Flask Security,我正在开发一个Flask应用程序,并使用Flask安全性进行用户身份验证(这反过来又使用Flask登录) 我有一条需要身份验证的路由,/user。我正在尝试编写一个单元测试,它测试对于经过身份验证的用户,这将返回适当的响应 在我的unittest中,我创建了一个用户并以该用户的身份登录,如下所示: from unittest import TestCase from app import app, db from models import User from flask_security.ut
/user
。我正在尝试编写一个单元测试,它测试对于经过身份验证的用户,这将返回适当的响应
在我的unittest中,我创建了一个用户并以该用户的身份登录,如下所示:
from unittest import TestCase
from app import app, db
from models import User
from flask_security.utils import login_user
class UserTest(TestCase):
def setUp(self):
self.app = app
self.client = self.app.test_client()
self._ctx = self.app.test_request_context()
self._ctx.push()
db.create_all()
def tearDown(self):
if self._ctx is not None:
self._ctx.pop()
db.session.remove()
db.drop_all()
def test_user_authentication():
# (the test case is within a test request context)
user = User(active=True)
db.session.add(user)
db.session.commit()
login_user(user)
# current_user here is the user
print(current_user)
# current_user within this request is an anonymous user
r = test_client.get('/user')
在测试中,当前用户返回正确的用户。但是,请求的视图总是将匿名用户
作为当前用户
返回
/user
路线定义为:
class CurrentUser(Resource):
def get(self):
return current_user # returns an AnonymousUser
我相当肯定我只是没有完全理解测试请求上下文是如何工作的。我已经读了很多这篇文章,但仍然不理解如何进行这个特定的单元测试。问题是
test\u client.get()
调用会导致推送一个新的请求上下文,因此您在设置()中推送的上下文
测试用例的方法不是/user
处理程序看到的方法
我认为文档和部分中显示的方法是测试登录的最佳方法。其思想是通过应用程序发送登录请求,就像普通客户端一样。这将负责在测试客户端的用户会话中注册已登录的用户。我不太喜欢所示的其他解决方案,主要是因为您必须将密码保存在单元测试文件中(我使用的是Flask LDAP登录,因此添加虚拟用户等不太明显),所以我绕过了它: 在我设置测试应用程序的地方,我添加了:
@app.route('/auto_login')
def auto_login():
user = ( models.User
.query
.filter_by(username="Test User")
.first() )
login_user(user, remember=True)
return "ok"
然而,我对flask应用程序的测试实例做了很多更改,比如使用不同的DB,在这里我构建了它,因此添加一个路由并不会使代码变得更混乱。Obv此路线在实际应用程序中不存在
那么我会:
def login(self):
response = self.app.test_client.get("/auto_login")
之后,使用
test\u客户端所做的任何操作都应登录。问题在于不同的请求上下文。
在普通的Flask应用程序中,每个请求都会创建一个新的上下文,该上下文将在整个链中重复使用,直到创建最终响应并将其发送回浏览器
当您创建并运行Flask测试并执行请求(例如,self.client.post(…)
)时,在收到响应后,上下文将被丢弃。因此,当前用户
始终是匿名用户
为了解决这个问题,我们必须告诉Flask在整个测试中重用相同的上下文。您可以通过简单地用以下内容包装代码来实现这一点:
with self.client:
您可以在以下精彩的文章中阅读更多关于此主题的内容:
示例
之前:
def test_that_something_works():
response = self.client.post('login', { username: 'James', password: '007' })
# this will fail, because current_user is an AnonymousUser
assertEquals(current_user.username, 'James')
之后:
def test_that_something_works():
with self.client:
response = self.client.post('login', { username: 'James', password: '007' })
# success
assertEquals(current_user.username, 'James')
从文档中:
在进行单元测试时,可以方便地全局关闭身份验证。要启用此功能,如果应用程序配置变量LOGIN\u DISABLED设置为True,则此装饰程序将被忽略。如果您真的显示了您实际正在做的事情,则会有所帮助-更新以显示测试的设置方式。无论我如何尝试,当前用户
始终是匿名用户。知道如何修复该行为吗?我猜您没有使用测试\u客户端
,或者您在请求\u上下文
或类似方面存在其他问题。在测试中,您必须非常小心地处理这些问题-确保您了解什么是请求上下文,并且知道您所处的上下文。谢谢您的回答。我用self将我的测试代码包装成。客户:
最佳答案,拯救了我的一天!