我正在为我的Flask应用程序构建测试,在其中一个测试中需要修改会话密钥(它本身就是一个值列表),然后检查修改后的密钥内容是否改变了应用程序行为。我正在使用Flask documentation中的方法来修改session
的测试。
这是一段摘录示例代码,用于演示问题(我已经添加了打印语句,以及它们在测试运行期间打印的内容):
my_app.py
from flask import (
Flask,
session,
)
app = Flask(__name__)
app.secret_key = 'bad secret key'
@app.route('/create_list/', methods=['POST'])
def create_list():
session['list'] = ['1', '2']
return "List created!"
@app.route('/in_list/')
def in_list():
print(str(session['list'])) # ['1', '2'], but why?
if '3' in session['list']:
return "session['list'] contains '3'!"
else:
return "Oy vey! '3' is not in the session['list']"
test_my_app.py
import flask
from unittest import TestCase
import my_app
class TestApp(TestCase):
def setUp(self):
self.test_client = my_app.app.test_client()
self.test_client.post('/create_list/')
def testAppendList(self):
with self.test_client as client:
with client.session_transaction() as sess:
sess['list'].append('3')
print(str(sess['list'])) # ['1', '2', '3'], as expected
response = client.get('/in_list/')
expected_response = "session['list'] contains '3'!".encode('ascii')
self.assertTrue(expected_response == response.data)
我的问题是:
session['list']
的正确方法是什么?答案 0 :(得分:2)
flask.session
modified
attribute提及:如果会话对象检测到修改,则为true。请注意,对可变结构的修改不会自动获取,在这种情况下,您必须自己将属性显式设置为True。
所以,问题1的答案是:它发生是因为list是一个可变结构,因此它在会话中的修改不会自动获取。
session.modified
设置为True
。因此, test_my_app.py 的修订代码如下所示:
import flask
from unittest import TestCase
import my_app
class TestApp(TestCase):
def setUp(self):
self.test_client = my_app.app.test_client()
self.test_client.post('/create_list/')
def testAppendList(self):
with self.test_client as client:
with client.session_transaction() as sess:
sess['list'].append('3')
sess.modified = True
response = client.get('/in_list/')
expected_response = "session['list'] contains '3'!".encode('ascii')
self.assertTrue(expected_response == response.data)
以下是我发现的一些案例(也有可能),我在挖掘这个问题时偶然发现了这个案例:
所以,像这样:
@app.route('/create/')
def create():
session['example'] = ['one', 'two']
session['example'].append('three')
session['example'].remove('one')
return str(session['example'])
将返回['two', 'three']
请考虑以下事项:
@app.route('/create/')
def create():
session['example'] = ['one', 'two']
return str(session['example'])
@app.route('/modify/')
def modify():
session['example'].append('four')
return str(session['example'])
@app.route('/display/')
def display():
return str(session['example'])
现在,运行该应用并访问以下网址:
.../create/ # ['one', 'two']
.../modify/ # ['one', 'two', 'four']
.../display/ # ['one', 'two'] still
render_template()
时,模板的出现取决于会话中的可变性。在这种情况下,session
将从当前上下文传递到模板中,这与前一种情况非常相似。假设我们有:
<强> my_app.py 强>
@app.route('/create/')
def create():
session['example'] = ['one', 'two']
return str(session['example'])
@app.route('/modify/')
def modify():
session['example'].append('four')
return render_template('my_template.html')
@app.route('/display/')
def display():
return str(session['example'])
<强> my_template.html 强>
<!doctype html>
<html>
<head><title>Display session['example']</title></head>
<body>
<div>
{% if session['example'] %}
{{ session['example'] }}
{% else %}
session['example'] is not set =(
{% endif %}
</div>
</body>
</html>
我们打电话后:
.../create/ # ['one', 'two']
.../modify/ # will render page containing ['one', 'two', 'four']
.../display/ # though, still ['one', 'two']