简体   繁体   English

使用app工厂时,在pytest测试中访问Flask测试客户端会话

[英]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.

相关问题 使用pytest的测试烧瓶应用程序找不到夹具客户端 - test flask app using pytest can't find fixture client 如何使用Pytest测试dockerized flask应用程序? - How to test dockerized flask app using Pytest? 使用 Flask 和 PyTest 测试 SqlAlchemy 会话事件 - Test SqlAlchemy session events with Flask and PyTest ModuleNotFoundError:尝试在 Windows 虚拟环境中使用 Pytest 和 Flask 创建测试时没有名为“app”的模块 - ModuleNotFoundError: No module named 'app' when trying to create a Test using Pytest and Flask on Windows virtual enviroment Pytest:无法让Flask应用程序在测试中运行 - Pytest: cannot get Flask app to behave in test 如何使用 flask 和 pytest 测试端点异常? - How to test an endpoint exception using flask and pytest? 使用test_client对Flask RESTful API进行单元测试时,等同于请求Session对象 - Equivalent of a requests Session object when unit testing a Flask RESTful API using a test_client 如何在pytest中完成每次测试后完全拆解烧瓶应用程序? - How to Completely Teardown Flask App After Each Test in pytest? 如何使用 pytest 测试使用 Flask 创建的路由? - How can I use pytest to test routes created using flask? 为什么要使用Flask的app.test_client()而不是requests.Session()进行测试 - Why use Flask's app.test_client() over requests.Session() for testing
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM