【问题标题】:Accessing Flask test client session in pytest test when using an app factory使用应用程序工厂时在 pytest 测试中访问 Flask 测试客户端会话
【发布时间】:2016-07-23 19:57:45
【问题描述】:

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

以下是 MWE。

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:

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:

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

请注意,直接运行它可以正常工作,我可以在 /set、/check、/clear 周围跳转,并且它的行为符合预期。同样,仅使用测试客户端获取页面的测试按预期工作。然而,直接访问会话似乎没有。

【问题讨论】:

    标签: python unit-testing flask pytest fixtures


    【解决方案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
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2019-02-08
        • 2020-05-27
        • 1970-01-01
        • 2019-09-13
        • 1970-01-01
        • 2017-08-23
        • 1970-01-01
        • 2022-01-12
        • 1970-01-01
        相关资源
        最近更新 更多