环境:
- Python 3.6.1
- 烧瓶 0.12.2
- Werkzeug 0.14.1
在为我的Flask应用程序编写测试时,我发现了以下特性:如果在 Flask 应用程序的测试中,您将被重定向到同一个 url 两次“连续” ClientRedirectError: loop detected
将被抛出,即使它在第二次重定向后停止重定向(即循环实际上并没有发生)。
考虑以下简化示例:
应用程序.py
from flask import (
Flask,
redirect,
url_for,
session
)
app = Flask(__name__)
app.secret_key = 'improper secret key'
@app.route('/')
def index():
if not session.get('test', False):
session['test'] = True
return redirect(url_for('index'))
else:
return "Hello"
@app.route('/redirection/')
def redirection():
# do something — login user, for example
return redirect(url_for('index'))
test_redirect.py
from unittest import TestCase
from app import app
class RedirectTestCase(TestCase):
def setUp(self):
self.test_client = app.test_client()
def testLoop(self):
response = self.test_client.get('/redirection/', follow_redirects=True)
self.assertTrue('Hello'.encode('ascii') in response.data)
现在,如果我要运行测试——它会抛出一个ClientRedirectError: loop detected
(尽管从代码中可以看出第二次重定向只会发生一次)。
如果我只是运行应用程序并转到/redirection/
- 它会/
毫无问题地将我带到索引(即),并且不会发生循环。
我需要if not session.get('test', False):
in的原因index()
是因为在我的应用程序中我使用它来设置一些东西session
,以防用户/
第一次访问。正如代码中的评论所建议的那样,在我的“真实”应用程序redirection()
中是一个让用户登录的功能。
我的问题是:
- 是否有一种“正确”的方法来克服
ClientRedirectError: loop detected
类似情况下的投掷问题(即是否有可能使测试运行并通过)? - 是否有更好/“更正确”的方式来
session
为“首次”用户设置内容? - 是否可以将提到的行为视为werkzeug中的错误(即实际循环没有发生,但
ClientRedirectError: loop detected
仍然被抛出)?
解决方法,我想出了(仍然没有回答我的问题):
def testLoop(self):
self.test_client.get('/redirection/') # removed follow_redirects=True
response = self.test_client.get('/', follow_redirects=True) # navigating to '/', directly
self.assertTrue('Hello'.encode('ascii') in response.data)
这可能看起来多余,但这只是一个简化的示例(如果self.test_client.get('/redirection/')
将其替换为self.test_client.post('/login/', data=dict(username='user', password='pass'))
.