How to create session variables in Selenium / Django Unit Test?

I am trying to write a functional test that Selenium uses to test Django performance. When a user arrives at a page ("page2"), the view that displays this page expects to find the session variable "uid" (user ID). I read half a dozen articles on how this should be done, but none of them worked for me. The code below shows how the Django documentation says that this should be done, but this also does not work for me. When I run the test, the view never completes, and I get a "server error" message. Can someone please tell me what I am doing wrong? Thanks.

views.py:

from django.shortcuts import render_to_response def page2(request): uid = request.session['uid'] return render_to_response('session_tests/page2.html', {'uid': uid}) 

test.py:

 from django.test import LiveServerTestCase from selenium import webdriver from django.test.client import Client class SessionTest(LiveServerTestCase): def setUp(self): self.browser = webdriver.Firefox() self.browser.implicitly_wait(3) self.client = Client() self.session = self.client.session self.session['uid'] = 1 def tearDown(self): self.browser.implicitly_wait(3) self.browser.quit() def test_session(self): self.browser.get(self.live_server_url + '/session_tests/page2/') body = self.browser.find_element_by_tag_name('body') self.assertIn('Page 2', body.text) 
+4
source share
3 answers

Here's how to solve this problem. James Islett hinted at a solution when he mentioned the session identifier above. jscn showed how to set up a session, but he did not mention the importance of the session key for the solution, nor did he discuss how to associate the session state with the Selenium browser object.

First, you need to understand that when creating a session key / value pair (e.g. 'uid' = 1), Django middleware will create a session / data / expiration record in your selection backend (database, file, and etc.). The response object will then send that session key to the cookie back to the client browser. When the browser sends a subsequent request, it will send back a cookie containing this key, which is then used by the middleware to search for user session elements.

Thus, a solution is required 1.) find a way to obtain the session key that is generated when the session item is created, and then; 2.) find a way to pass this key to the cookie via the Selenium Firefox web browser. Here is the code that does this:

 selenium_test.py: ----------------- from django.conf import settings from django.test import LiveServerTestCase from selenium import webdriver from django.test.client import Client import pdb def create_session_store(): """ Creates a session storage object. """ from django.utils.importlib import import_module engine = import_module(settings.SESSION_ENGINE) # Implement a database session store object that will contain the session key. store = engine.SessionStore() store.save() return store class SeleniumTestCase(LiveServerTestCase): def setUp(self): self.browser = webdriver.Firefox() self.browser.implicitly_wait(3) self.client = Client() def tearDown(self): self.browser.implicitly_wait(3) self.browser.quit() def test_welcome_page(self): #pdb.set_trace() # Create a session storage object. session_store = create_session_store() # In pdb, you can do 'session_store.session_key' to view the session key just created. # Create a session object from the session store object. session_items = session_store # Add a session key/value pair. session_items['uid'] = 1 session_items.save() # Go to the correct domain. self.browser.get(self.live_server_url) # Add the session key to the cookie that will be sent back to the server. self.browser.add_cookie({'name': settings.SESSION_COOKIE_NAME, 'value': session_store.session_key}) # In pdb, do 'self.browser.get_cookies() to verify that it there.' # The client sends a request to the view that expecting the session item. self.browser.get(self.live_server_url + '/signup/') body = self.browser.find_element_by_tag_name('body') self.assertIn('Welcome', body.text) 
+2
source

There are several tickets to the Django-error tracker around these kinds of problems, the main of which is: https://code.djangoproject.com/ticket/10899 , which hasn had some movement for several months. Basically, you need to do some extra tweaking to get the session to work correctly. Here's what worked for me (it may not work as it did with your specific setup since I did not use Selenium):

 def setUp(self): from django.conf import settings engine = import_module(settings.SESSION_ENGINE) store = engine.SessionStore() store.save() self.client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key 

You should now have access to self.client.session , and it should be mindful of any changes you make to it.

0
source

Here is my solution for Django == 2.2.

  from importlib import import_module from django.conf import settings from django.contrib.auth import get_user_model # create the session database instance engine = import_module(settings.SESSION_ENGINE) session = engine.SessionStore() # create the user and instantly login User = get_user_model() temp_user = User.objects.create(username='admin') temp_user.set_password('password') self.client.login(username='admin', password='password') # get session object and insert data session = self.client.session session[key] = value session.save() # update selenium instance with sessionID selenium.add_cookie({'name': 'sessionid', 'value': session._SessionBase__session_key, 'secure': False, 'path': '/'}) 
0
source

All Articles