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

问题描述 投票:4回答:2

我正在尝试使用pytest和app工厂对应用程序进行单元测试,但我似乎无法在我的测试中访问客户端会话对象。我确定有一些背景我不是在推动某个地方。我在我的'app'夹具中推送应用程序上下文。我应该在某处推送请求上下文吗?

以下是MWE。

美味哦.朋友:

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()

conf test.朋友:

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.朋友:

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

请注意,直接运行它可以正常工作,我可以跳转/设置,/检查,/清除它,它的行为符合预期。类似地,仅使用测试客户端来获取页面的测试按预期工作。但是,似乎没有直接访问会话。

python unit-testing flask pytest fixtures
2个回答
1
投票

问题在于您使用测试客户端的方式。

首先,您不必创建客户端夹具。如果你使用pytest-flask,它提供了一个client夹具使用。如果您仍想使用自己的客户端(可能因为您不想要pytest-flask),您的客户端夹具应该充当上下文处理器来包装您的请求。

所以你需要以下内容:

def test_value_set_in_session(client):
    with client:
        client.get('/set')
        assert 'key' in session

当天的信息:pytest-flask有一个类似的客户夹具。区别在于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

你使用pytest-flask client进行测试

def test_value_set_in_session(client):
    client.get('/set')
    assert 'key' in session

1
投票

在cookiecutter-flask中查看conftest.py中的以下内容。它可能会给你一些想法。

@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)
© www.soinside.com 2019 - 2024. All rights reserved.