[英]Accessing Flask test client session in pytest test when using an app factory
I'm trying to unittest an application using pytest and an app factory, but I can't seem to get access to the client session object in my tests. 我正在尝试使用pytest和app工厂对应用程序进行单元测试,但我似乎无法在我的测试中访问客户端会话对象。 I'm sure there's some context I'm not pushing somewhere.
我确定有一些背景我不是在推动某个地方。 I push the app context in my 'app' fixture.
我在我的'app'夹具中推送应用程序上下文。 Should I push the request context somewhere?
我应该在某处推送请求上下文吗?
The following is an MWE. 以下是MWE。
mwe.py: mwe.py:
from flask import Flask, session
def create_app():
app = Flask(__name__)
app.secret_key = 'top secret'
@app.route('/set')
def session_set():
session['key'] = 'value'
return 'Set'
@app.route('/check')
def session_check():
return str('key' in session)
@app.route('/clear')
def session_clear():
session.pop('key', None)
return 'Cleared'
return app
if __name__ == "__main__":
mwe = create_app()
mwe.run()
conftest.py: conftest.py:
import pytest
from mwe import create_app
@pytest.fixture(scope='session')
def app(request):
app = create_app()
ctx = app.app_context()
ctx.push()
def teardown():
ctx.pop()
request.addfinalizer(teardown)
return app
@pytest.fixture(scope='function')
def client(app):
return app.test_client()
test_session.py: test_session.py:
import pytest
from flask import session
def test_value_set_for_client_request(client): # PASS
client.get('/set')
r = client.get('/check')
assert 'True' in r.data
def test_value_set_in_session(client): # FAIL
client.get('/set')
assert 'key' in session
def test_value_set_in_session_transaction(client): # FAIL
with client.session_transaction() as sess:
client.get('/set')
assert 'key' in sess
Note that running this directly works fine, I can jump around /set, /check, /clear and it behaves as expected. 请注意,直接运行它可以正常工作,我可以跳转/设置,/检查,/清除它,它的行为符合预期。 Similarly, the test that uses only the test client to GET the pages works as expected.
类似地,仅使用测试客户端来获取页面的测试按预期工作。 Accessing the session directly however doesn't seem to.
但是,似乎没有直接访问会话。
Take a look at the following from conftest.py in cookiecutter-flask. 从cookiecutter -flask中的conftest.py查看以下内容。 It may give you some ideas.
它可能会给你一些想法。
@pytest.yield_fixture(scope='function')
def app():
"""An application for the tests."""
_app = create_app(TestConfig)
ctx = _app.test_request_context()
ctx.push()
yield _app
ctx.pop()
@pytest.fixture(scope='function')
def testapp(app):
"""A Webtest app."""
return TestApp(app)
The problem is with the way you use your test client. 问题在于您使用测试客户端的方式。
First of all you don't have to create your client fixture. 首先,您不必创建客户端夹具。 If you use
pytest-flask
, it offers a client
fixture to use. 如果你使用
pytest-flask
,它提供了一个client
装置来使用。 If you still want to use your own client though (maybe because you don't want pytest-flask
), your client fixture should act as a context processor to wrap your requests around. 如果您仍想使用自己的客户端(可能因为您不想使用
pytest-flask
),您的客户端夹具应该充当上下文处理器来包装您的请求。
So you need something like the following: 所以你需要以下内容:
def test_value_set_in_session(client):
with client:
client.get('/set')
assert 'key' in session
information of the day: pytest-flask has a similar client fixture to yours. 当天的信息:pytest-flask有一个类似的客户夹具。 The difference is that pytest-flask uses a context manager to give you a client and that saves you 1 line per test
区别在于pytest-flask使用上下文管理器为您提供客户端,每次测试可节省1行
@pytest.yield_fixture
def client(app):
"""A Flask test client. An instance of :class:`flask.testing.TestClient`
by default.
"""
with app.test_client() as client:
yield client
your test with pytest-flask
client
你用
pytest-flask
client
测试
def test_value_set_in_session(client):
client.get('/set')
assert 'key' in session
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.