Django 测试:User.authenticate 失败
Django Tests: User.authenticate fails
我已经被这个问题困扰了几个小时。我是 django 和自动化测试的新手,我一直在玩弄 Selenium 和 django 的 StaticLiveServerTestCase。我一直在尝试测试我的登录表单(顺便说一下,当我使用 runserver 并自己测试时它工作正常。)
一切正常,除了我似乎无法成功登录我的测试用户。我已经将断点缩小到 django 的 User.authenticate 方法。
用户对象在我的设置中成功创建,我可以通过在我的测试方法中访问它的属性来确认。但是,身份验证失败。
我查看了以下内容以寻求帮助,但它们并没有让我走得太远:
- Django Unittests Client Login: fails in test suite, but not in Shell
知道身份验证失败的原因吗?我需要在我的设置中添加一些东西吗?
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")
我已经被这个问题困扰了几个小时。我是 django 和自动化测试的新手,我一直在玩弄 Selenium 和 django 的 StaticLiveServerTestCase。我一直在尝试测试我的登录表单(顺便说一下,当我使用 runserver 并自己测试时它工作正常。)
一切正常,除了我似乎无法成功登录我的测试用户。我已经将断点缩小到 django 的 User.authenticate 方法。
用户对象在我的设置中成功创建,我可以通过在我的测试方法中访问它的属性来确认。但是,身份验证失败。
我查看了以下内容以寻求帮助,但它们并没有让我走得太远:
- Django Unittests Client Login: fails in test suite, but not in Shell
知道身份验证失败的原因吗?我需要在我的设置中添加一些东西吗?
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")