DEV Community

Cover image for Python: pytest accessing Flask session and request context variables.
Be Hai Nguyen
Be Hai Nguyen

Posted on

6

Python: pytest accessing Flask session and request context variables.

How to enable pytest methods to access Flask's context variables, session and request.

I've previously blogged about pytest's application fixture and test client fixture in Python: pytest and Flask template context processor functions. ( Please see section pytest entry module conftest.py. )

The test client fixture in the mentioned post:

@pytest.fixture(scope='module')
def test_client( app ):
    """
    Creates a test client.
    app.test_client() is able to submit HTTP requests.

    The app argument is the app() fixture above.    
    """

    with app.test_client() as testing_client:
        yield testing_client  # Return to caller.
Enter fullscreen mode Exit fullscreen mode

When testing the codes that access Flask’s context variable session, the above fixture will not work. To access this variable, the official document states:

If you want to access or set a value in the session before making a request, use the client’s session_transaction() method in a with statement. It returns a session object, and will save the session once the block ends.

https://flask.palletsprojects.com/en/2.2.x/testing/

I tried that, and it does not work... It's a “popular” problem. It's been around for a few years. There are a few posts on it, however, most suggestions fail to work for me.

Sessions are empty when testing #69 raises this problem, and user russmac suggests a solution:

@pytest.fixture(scope='module')
def test_client( app ):
    """
    Creates a test client.
    app.test_client() is able to submit HTTP requests.

    The app argument is the app() fixture above.    
    """

    with app.test_client() as testing_client:
        """
        See: https://github.com/pytest-dev/pytest-flask/issues/69 
        Sessions are empty when testing #69 
        """
        with testing_client.session_transaction() as session:
            session['Authorization'] = 'redacted'

        yield testing_client  # Return to caller.
Enter fullscreen mode Exit fullscreen mode

This works for me. However, to access variable session my test codes must be within:

with app.test_request_context():
Enter fullscreen mode Exit fullscreen mode

Or else, it raises the error RuntimeError: Working outside of request context. Also, without the above call, the codes proper would not be able to access the request variable during testing.

Following is a proper test method of a project I'm working on:

@pytest.mark.timesheet_bro
def test_close( app ):
    bro_obj = TimesheetBRO( 1 )

    #
    # RuntimeError: Working outside of request context.
    #
    # session[ 'user_id' ] = 100
    #

    with app.test_request_context( '?searchType={}'.format(UNRESTRICT_SEARCH_TYPE) ):
        assert request.args[ 'searchType' ] == UNRESTRICT_SEARCH_TYPE
        assert request.values.get( 'searchType' ) == UNRESTRICT_SEARCH_TYPE

        session[ 'user_id' ] = 1

        data = bro_obj.close( 326 )

    assert bro_obj.last_message == ''
    assert data['status']['code'] == HTTPStatus.OK.value
Enter fullscreen mode Exit fullscreen mode

Please note, within the codes proper, session[ 'user_id' ] is set after a user has successfully logged in. Setting this value in the test codes to create a correct pre-condition for the codes being tested. Please also note, request.values.get( 'searchType' ) is also used in the codes under testing.

Following is another proper test method which does not submit any request parameters:

@pytest.mark.timesheet_bro
def test_update_last_timesheet_id( app ):
    bro_obj = TimesheetBRO( 1 )

    with app.test_request_context():
        session[ 'user_id' ] = 1

        data = bro_obj.update_last_timesheet_id( 1, 1123 )

    assert bro_obj.last_message == ''
    assert data['status']['code'] == HTTPStatus.OK.value
Enter fullscreen mode Exit fullscreen mode

I hope you will find this helpful at some point... And thank you for reading.

Image of AssemblyAI tool

Transforming Interviews into Publishable Stories with AssemblyAI

Insightview is a modern web application that streamlines the interview workflow for journalists. By leveraging AssemblyAI's LeMUR and Universal-2 technology, it transforms raw interview recordings into structured, actionable content, dramatically reducing the time from recording to publication.

Key Features:
🎥 Audio/video file upload with real-time preview
🗣️ Advanced transcription with speaker identification
⭐ Automatic highlight extraction of key moments
✍️ AI-powered article draft generation
📤 Export interview's subtitles in VTT format

Read full post

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay