使用Python Unittest在烧瓶中进行测试重定向
我目前正试图为我的Flask应用程序编写一些单元测试。在我的许多视图功能(例如我的登录)中,我重定向到一个新页面。例如:使用Python Unittest在烧瓶中进行测试重定向,python,unit-testing,flask,python-unittest,Python,Unit Testing,Flask,Python Unittest,我目前正试图为我的Flask应用程序编写一些单元测试。在我的许多视图功能(例如我的登录)中,我重定向到一个新页面。例如: @user.route('/login', methods=['GET', 'POST']) def login(): .... return redirect(url_for('splash.dashboard')) 我试图验证这个重定向是否发生在我的单元测试中。现在,我有: def test_register(self): rv = self.c
@user.route('/login', methods=['GET', 'POST'])
def login():
....
return redirect(url_for('splash.dashboard'))
我试图验证这个重定向是否发生在我的单元测试中。现在,我有:
def test_register(self):
rv = self.create_user('John','Smith','John.Smith@myschool.edu', 'helloworld')
self.assertEquals(rv.status, "200 OK")
# self.assert_redirects(rv, url_for('splash.dashboard'))
此函数确实确保返回的响应为200,但最后一行显然不是有效的语法。我怎么能断言这一点?我的create\u user
功能很简单:
def create_user(self, firstname, lastname, email, password):
return self.app.post('/user/register', data=dict(
firstname=firstname,
lastname=lastname,
email=email,
password=password
), follow_redirects=True)
试一试
有一个api供你使用
assertRedirects(response, location)
Checks if response is an HTTP redirect to the given location.
Parameters:
response – Flask response
location – relative URL (i.e. without http://localhost)
测试脚本:
def test_register(self):
rv = self.create_user('John','Smith','John.Smith@myschool.edu', 'helloworld')
assertRedirects(rv, url of splash.dashboard)
Flask有一个测试客户机和一个测试客户机,它非常适合这样的功能
from flask import url_for, request
import yourapp
test_client = yourapp.app.test_client()
with test_client:
response = test_client.get(url_for('whatever.url'), follow_redirects=True)
# check that the path changed
assert request.path == url_for('redirected.url')
对于旧版本的Flask/Werkzeug,可在以下回复中获得请求:
from flask import url_for
import yourapp
test_client = yourapp.app.test_client()
response = test_client.get(url_for('whatever.url'), follow_redirects=True)
# check that the path changed
assert response.request.path == url_for('redirected.url')
文档中有更多关于如何执行此操作的信息,尽管仅供参考,如果您看到“flaskr”,这是测试类的名称,而不是flaskr中的任何内容,这让我第一次看到它时感到困惑。一种方法是不遵循重定向(从您的请求中删除
follow\u redirects
,或者显式地将其设置为False
)
然后,您只需将self.assertEquals(rv.status,“200 OK”)替换为:
self.assertEqual(rv.status_code, 302)
self.assertEqual(rv.location, url_for('splash.dashboard', _external=True))
如果出于某种原因想继续使用
follow\u redirects
,另一种(稍微脆弱的)方法是检查一些预期的仪表板字符串,例如rv.data
响应中的HTML元素ID。e、 g.self.assertIn('dashboard-id',rv.data)
您可以使用Flask作为一个标记(使用带有关键字的)来验证重定向后的最终路径。它允许保留最终请求上下文,以便导入包含请求的路径
来自flask导入请求的url\u
def测试_寄存器(自身):
使用self.app.test_client()作为客户端:
用户数据=dict(
名字是“约翰”,
lastname='Smith',
给约翰发电子邮件。Smith@myschool.edu',
密码='helloworld'
)
res=client.post('/user/register',data=user\u data,follow\u redirects=True)
assert res.status==“200正常”
assert request.path==url\u for('splash.dashboard')
我强烈鼓励人们使用此解决方案,它消除了烧瓶测试依赖性(通常,我认为使用尽可能少的扩展是一件好事,或者只使用“稳定”和“大”扩展,如烧瓶主体、烧瓶安全性等)。但是,此解决方案会引发运行时错误:试图在不推送应用程序上下文的情况下生成URL。这必须在应用程序上下文可用时执行
,因为的url\u需要应用程序上下文。你所要做的就是将它放入一个带有app.app_context()的:
“response.request”-->AttributeError:“response”对象没有属性“request”不确定response.request
是什么,但是如果你将与app.test_client()一起作为c:
使用来保持请求上下文,然后您就可以导入request和url_for并执行request.path==url_for(…
从我的测试中,我认为使用request.path
不起作用,因为路径设置为初始url,而不是重定向后的url。@dyruss从我的测试中,我可以确认使用客户机作为上下文(与客户机)调用client.get
时,是否更改request
上下文(并遵循\u redirects=True)。谢谢@DyRuss