How to Create Session Variables in Selenium/Django Unit Test?
source link: https://stackoverflow.com/questions/14320873/how-to-create-session-variables-in-selenium-django-unit-test/57113280#57113280
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Join Stack Overflow to learn, share knowledge, and build your career.
I'm trying to write a functional test that uses Selenium to test a Django view. When the user comes to a page ("page2"), the view that renders that page expects to find a session variable "uid" (user ID). I've read a half dozen articles on how this is supposed to be done but none of them have worked for me. The code below shows how the Django documentation says it should be done but it doesn't work for me either. When I run the test, the view never completes executing and I get a "server error occurred" message. Could someone please tell me what I'm doing wrong? Thank you.
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)
Here's how to solve this problem. James Aylett hinted at the solution when he mentioned the session ID above. jscn showed how to set up a session but he didn't mention the importance of the session key to a solution and he also didn't discuss how to link the session state to Selenium's browser object.
First, you have to understand that when you create a session key/value pair (e.g. 'uid'=1), Django's middleware will create a session key/data/expiration date record in your backend of choice (database, file, etc.). The response object will then send that session key in a cookie back to the client's browser. When the browser sends a subsequent request, it will send a cookie back that contains that key which is then used by the middleware to lookup the user's session items.
Thus, the solution required 1.) finding a way to obtain the session key that is generated when you create a session item and then; 2.) finding a way to pass that key back in a cookie via Selenium's Firefox webdriver browser object. Here's the code that does that:
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's there.'
# The client sends a request to the view that's 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)
There are a couple of tickets in Django's bug tracker around this kind of problem, the main one seems to be: https://code.djangoproject.com/ticket/10899 which hasn't had any movement on it for a few months. Basically, you need to do some extra set up to get the session to work properly. Here's what worked for me (may not work as is with your particular set up, as I wasn't using 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
Now you should be able to access self.client.session
and it should remember any changes you make to it.
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': '/'})
Your Answer
Post as a guest
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy
Not the answer you're looking for? Browse other questions tagged django django-views selenium-webdriver or ask your own question.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK