Search code examples
djangoseleniumdjango-authenticationdjango-tests

Django Tests: User.authenticate fails


I've been stuck on this problem for a couple hours. I'm new to django and automated testing, and I've been playing around with Selenium and django's StaticLiveServerTestCase. I've been trying to test my login form (which works fine when I use runserver and test it myself, by the way.)

Everything is working great, except I can't seem to successfully login my test user. I've narrowed down the break point to django's User.authenticate method.

The User object is created successfully in my setUp and I can confirm that by accessing it's attributes in my test method. However, authenticate fails.

I've looked at the following for help but they didn't get me very far:

Any idea why authenticate fails? Do I need to add something to my settings?

from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from django.contrib.auth.models import User

from django.contrib.auth import authenticate


class AccountTestCase(StaticLiveServerTestCase):
    def setUp(self):
        self.selenium = webdriver.Chrome()
        super().setUp()
        User.objects.create(username='test', email='test@test.com', password='Test1234', is_active=True)

    def tearDownClass(self):
        self.selenium.quit()
        super().tearDown()

    def test_register(self):
        user = authenticate(username='test', password='Test1234')
        if user is not None: # prints Backend login failed
            print("Backend login successful")
        else:
            print("Backend login failed")

    user = User.objects.get(username='test')
    print(user)
    print(user.username) # prints test
    print(user.password) # prints Test1234

Solution

  • I found the issue. The User.authenticate() method hashes the password provided. However, I set the password directly when creating the user, which means it was stored as Test1234, so the hashed password provided during authentication did not match 'Test1234', hence the failure.

    To properly store a hashed password, you need to use the set_password() method.

    Updated setUp code:

    def setUp(self):
        self.selenium = webdriver.Chrome()
        super().setUp()
        user = User.objects.create(username='test', email='test@test.com', is_active=True)
        user.set_password('Test1234')
        user.save()