Logo

dev-resources.site

for different kinds of informations.

Python: pytest accessing Flask session and request context variables.

Published at
8/18/2022
Categories
python
pytest
session
request
Author
behainguyen
Categories
4 categories in total
python
open
pytest
open
session
open
request
open
Author
11 person written this
behainguyen
open
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.

request Article's
30 articles in total
Favicon
important status code to be known as API developer
Favicon
HTTP Headers in API
Favicon
Mastering API Request Chaining: Essential Techniques for Developers
Favicon
Increasing API Reliability: Adding Timeouts to Node.js Fetch
Favicon
Python and APIs: how to use Python to connect and interact with APIs
Favicon
Rails Request specs with arbitrary JSON params
Favicon
Criando react hook personalizado para fazer requisições
Favicon
HTTPS: Is it better than HTTP?
Favicon
Python: pytest accessing Flask session and request context variables.
Favicon
[HELP] Spring Boot: field is not set in request
Favicon
I'm Looking for Beta Readers
Favicon
An alternative API mocking library for frontend developers
Favicon
How to send request to join a organization in github
Favicon
Negotiating Languages with Ruby: A Journey through Linguistic Diversity
Favicon
Event-driven architecture over standard client-server aproach
Favicon
Roll your own Request object in Laravel
Favicon
Mezon wrapper for processing HTTP requests
Favicon
Preventing memory leak by handling errors and request cancellations separately in Axios
Favicon
How do you present a PR?
Favicon
How can i access the request object inside a nuxtJS module?
Favicon
React Js Axios Post Request Example Tutorial
Favicon
How to make API request from command line with CURL
Favicon
Request for Node.js has been deprecated
Favicon
NodeJS http homepage 20: request url with link menu
Favicon
Sharing the context with the model in an Express app
Favicon
A simple and useful #react component for helping with asynchronous loading/fetch data
Favicon
Feature request: @mention a user
Favicon
We want Dev.to REST API :)
Favicon
Perform small coding tasks for a reliable source of income?
Favicon
When to request data in SPA

Featured ones: