How to Create Session Variables in Selenium/Django Unit Test?

谁说我不能喝 提交于 2019-12-05 01:36:33

问题


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)

回答1:


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)



回答2:


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.




回答3:


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': '/'})


来源:https://stackoverflow.com/questions/14320873/how-to-create-session-variables-in-selenium-django-unit-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!