Flask Testing Accessing and manipulating session variables in your tests using Flask-Testing


Example

Most of the web applications use the session object to store some important information. This examples show how you can test such application using Flask-Testing. Full working example is also available on github.

So first install Flask-Testing in your virtualenv

pip install flask_testing

To be able to use the session object you have to set the secret key

app.secret_key = 'my-seCret_KEy'

Let's imagine you have in your application function that need to store some data in session variables like this

@app.route('/getSessionVar', methods=['GET', 'POST'])
def getSessionVariable():
  if 'GET' == request.method:
    session['sessionVar'] = 'hello'
  elif 'POST' == request.method:
    session['sessionVar'] = 'hi'
  else:
    session['sessionVar'] = 'error'

  return 'ok'

To test this function you can import flask_testing and let your test class inherit flask_testing.TestCase. Import also all the necessary libraries

import flask
import unittest
import flask_testing
from myapp.run import app
    
class TestMyApp(flask_testing.TestCase):

Very important before you start testing is to implement the function create_app otherwise there will be exception.

  def create_app(self):
    return app

To test your application is working as wanted you have a couple of possibilities. If you want to just assure your function is setting particular values to a session variable you can just keep the context around and access flask.session

def testSession1(self):
    with app.test_client() as lTestClient:
      lResp= lTestClient.get('/getSessionVar')
      self.assertEqual(lResp.status_code, 200)
      self.assertEqual(flask.session['sessionVar'], 'hello')

One more useful trick is to differentiate between GET and POST methods like in the next test function

def testSession2(self):
    with app.test_client() as lTestClient:
      lResp= lTestClient.post('/getSessionVar')
      self.assertEqual(lResp.status_code, 200)
      self.assertEqual(flask.session['sessionVar'], 'hi')

Now imagine your function expects a session variable to be set and reacts different on particular values like this

@app.route('/changeSessionVar')
def changeSessionVariable():
  if session['existingSessionVar'] != 'hello':
    raise Exception('unexpected session value of existingSessionVar!')

  session['existingSessionVar'] = 'hello world'
  return 'ok'

To test this function you have to use so called session transaction and open the session in the context of the test client. This function is available since Flask 0.8

def testSession3(self):
    with app.test_client() as lTestClient:
      #keep the session
      with lTestClient.session_transaction() as lSess:
        lSess['existingSessionVar'] = 'hello'

      #here the session is stored
      lResp = lTestClient.get('/changeSessionVar')
      self.assertEqual(lResp.status_code, 200)
      self.assertEqual(flask.session['existingSessionVar'], 'hello world')

Running the tests is as usual for unittest

if __name__ == "__main__":
    unittest.main()

And in the command line

python tests/test_myapp.py

Another nice way to run your tests is to use unittest Discovery like this:

python -m unittest discover -s tests