Greg Aker

Testing Django views that rely on session variables.

Filed in: Django

August 29, 2011

I'm working on a Django project where I rely on some session variables for logged in users in the templates. Being relatively inexperienced unit testing Django views, but wanting to become a bad-ass, I was having a tough time figuring out how to get session variables working in my test methods.

The basic test class looked like:

from django.core.urlresolvers import reverse
from django.test import Client, TestCase
from myapp.models import Blog

class BlogAdminTestCase(TestCase):

    def setUp(self):
        self.client = Client()

        s = self.client.session
        s['the_answer_to_life_and_everything'] = 42
        s.save()

    # Actual Tests Here...

However, every time I ran the tests, I'd get: AttributeError: 'dict' object has no attribute 'save' on the session object. Okay, that doesn't make sense. Running some debug code, it is a dictionary. The docs tell you to use that save() method, so I'm really confused! Googling around for a bit, it seems that a lot of people have run into this issue, but there weren't a lot of answers given. So here's how I fixed the problem.

from django.core.urlresolvers import reverse
from django.test import Client, TestCase
from myapp.models import Blog

class BlogAdminTestCase(TestCase):

    def setUp(self):
        self.client = Client()

        # Setup Test User
        User.objects.create_superuser(
            'fred_flinstone',
            'fred@heavydinosaurslocal211.org',
            'I love wilma12'  # yes this is a joke
        )

        self.client.login(username='fred_flinstone',
                          password='I love wilma12')

        s = self.client.session
        s['the_answer_to_life_and_everything'] = 42
        s.save()

    # Actual Tests Here...

Create a user, log them in and self.client.session is now an object and no longer a dictionary. If you take a step back and think about it, it makes so much sense. I feel really silly.

Back to writing more tests.