Django 测试:User.authenticate 失败

Django Tests: User.authenticate fails

我已经被这个问题困扰了几个小时。我是 django 和自动化测试的新手,我一直在玩弄 Selenium 和 django 的 StaticLiveServerTestCase。我一直在尝试测试我的登录表单(顺便说一下,当我使用 runserver 并自己测试时它工作正常。)

一切正常,除了我似乎无法成功登录我的测试用户。我已经将断点缩小到 django 的 User.authenticate 方法。

用户对象在我的设置中成功创建,我可以通过在我的测试方法中访问它的属性来确认。但是,身份验证失败。

我查看了以下内容以寻求帮助,但它们并没有让我走得太远:

知道身份验证失败的原因吗?我需要在我的设置中添加一些东西吗?

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

我发现了问题。 User.authenticate() 方法散列提供的密码。但是,我在创建用户时直接设置了密码,也就是说它被存储为Test1234,所以验证时提供的散列密码与'Test1234'不匹配,因此失败。

要正确存储散列密码,您需要使用 set_password() 方法。

更新设置代码:

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()

用户身份验证正在通过,但是当我尝试使用相同的凭据登录时,登录失败。

from django.contrib.auth.models import User
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.test import Client
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.webdriver import WebDriver
import time
from django.contrib.auth import authenticate

#from apps.digital.models import User


class MyTests(StaticLiveServerTestCase):

    port = 0
    host = '<my host>'

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



    def tearDown(self):
        self.selenium.quit()
        super(MyTests, self).tearDown()

    def test_login(self):
        self.user = authenticate(username='test', password='Test1234')
        if self.user is not None:  # prints Backend login failed
            self.user = User.objects.get(username='test')
            print(self.user.username)  # prints test
            print(self.user.password)  # prints Test1234
            self.login = self.client.login(username='test', password='Test1234')
            self.assertEqual(self.login, True)
            print("Backend login successful")

            self.selenium.get('%s%s' % (self.live_server_url, '/admin/'))
            username_input = self.selenium.find_element_by_name("username")
            username_input.send_keys(self.user.username)
            password_input = self.selenium.find_element_by_name("password")
            password_input.send_keys('Test1234')
            self.selenium.find_element_by_xpath('//input[@value="Log in"]').click()
            time.sleep(1)

        else:
            print("Backend login failed")

使用 create_superuser 解决了问题。下面的代码解决了它。

from django.contrib.auth.models import User
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.test import Client
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.webdriver import WebDriver
import time
from django.contrib.auth import authenticate

#from apps.digital.models import User


class MyTests(StaticLiveServerTestCase):

    port = 0
    host = 'my host'

    def setUp(self):
        super(MyTests, self).setUp()
        self.selenium = WebDriver()
        self.client = Client()
        self.user = User.objects.create_superuser(username='test', password='Test1234', email='test@test.com', is_active=True)
        self.user.save()

    def tearDown(self):
        self.selenium.quit()
        super(MyTests, self).tearDown()

    def test_login(self):
        self.user = authenticate(username='test', password='Test1234')
        if self.user is not None:  # prints Backend login failed
            self.user = User.objects.get(username='test')
            print(self.user.username)  # prints test
            print(self.user.password)  # prints Test1234
            self.login = self.client.login(username='test', password='Test1234')
            self.assertEqual(self.login, True)
            print("Backend login successful")

            self.selenium.get('%s%s' % (self.live_server_url, '/admin/'))
            username_input = self.selenium.find_element_by_name("username")
            username_input.send_keys(self.user.username)
            password_input = self.selenium.find_element_by_name("password")
            password_input.send_keys('Test1234')
            self.selenium.find_element_by_xpath('//input[@value="Log in"]').click()
            time.sleep(1)

        else:
            print("Backend login failed")