问题描述
我正在尝试为Django应用程序编写集成测试,以测试密码是否已从其他API更改.但是,在调用密码更改API后,无法测试新密码.
I'm trying to write an integration test for a Django application to test if the password was changed from a rest API. However, after calling the password change API, testing for the new password doesn't work.
我在这里做的是:我通过一个电话呼叫将密码更改为johnjohn
,然后尝试检查密码是否实际更改
What I'm doing here is: I change the password to johnjohn
through a rest call, then try to check if the password is actually changed
我的单元测试文件
import json
import urllib
import urllib2
import requests
from django.contrib.auth.models import User
from django.test import TestCase
from adaptors.redis_class import DjangoRedis
class PasswordChange(TestCase):
def setUp(self):
User.objects.create_user(username='john', email='[email protected]', password='john')
# class for redis access
r = DjangoRedis()
r.set("email:[email protected]", '0' * 40, ex=3600)
r.set('0' * 40, "email:[email protected]", ex=3600)
def test_change_password(self):
# Fake url I set through redis
url = 'http://127.0.0.1:8000/reset/' + '0' * 40 + '/'
r = requests.get(url)
csrf_token = r.content.split('csrf_token')[1].split('"')[2]
payload = {'csrfmiddlewaretoken': csrf_token, 'payload': json.dumps({'password': 'johnjohn'})}
headers = {'Cookie': 'csrftoken=' + csrf_token}
data = urllib.urlencode(payload)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
json_res = json.loads(response.read())
# This doesn't fail
self.assertEqual(json_res['password_changed'], True)
u = User.objects.get(username='john')
# This fails
self.assertEqual(u.check_password('johnjohn'),True)
我的观点
import hashlib
import random
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404
from django.http import JsonResponse
from django.shortcuts import render
from django.views.generic import View
from adaptors.redis_class import DjangoRedis
from constants import PASSWORD_RESET
from tasks import send_email
from util.rest import get_payload
class ResetPage(View):
def post(self, requests, reset_token):
r = DjangoRedis()
token = r.get(reset_token)
if token is None:
return JsonResponse({"token": False})
payload = get_payload(requests.POST)
try:
email = token.split(':')[1].lower()
u = User.objects.get(email=email)
u.set_password(payload['password'])
u.save()
r.delete(reset_token)
r.delete('email:' + email)
return JsonResponse({'password_changed': True})
except ValueError:
return JsonResponse({"password_changed": False, 'error': "can't get your email from the database (E01)"})
except ObjectDoesNotExist:
return JsonResponse({"password_changed": False, 'error': "User doesn't exist (E02)"})
def get(self, requests, reset_token):
r = DjangoRedis()
if not r.get(reset_token):
raise Http404
return render(requests, "login/reset.html", {'token': reset_token})
在unittests
目录中,单元测试文件称为rest_pass_login_tests.py
.
The unittest file is called rest_pass_login_tests.py
in a unittests
directory.
我使用以下命令运行它.
I run it by using the following command.
./manage.py test unittests/ --pattern="rest_pass_login_tests.py"
./manage.py test unittests/ --pattern="rest_pass_login_tests.py"
当我通过浏览器正常测试时,密码更改可以正常进行.但是,当我尝试通过单元测试检查密码是否已更改时,我收到了无效的密码.
When I test normally through the browser, the password change works fine. However, when I try to check if the password was changed or not through a unittest, I get an invalid password.
我在做什么错了?
推荐答案
我正在使用开发服务器运行单元测试.更改密码后,实际上是在发布到开发服务器,而不是测试服务器.
I was using dev server to run unittests. When I changed my password, I was actually posting to the dev server instead of the test one.
这是我的新单元测试
import json
from django.contrib.auth.models import User
from django.test import Client
from django.test import TestCase
from adaptors.redis_class import DjangoRedis
class PasswordChange(TestCase):
def setUp(self):
User.objects.create_user(username='john', email='[email protected]', password='john')
r = DjangoRedis()
r.set("email:[email protected]", '0' * 40, ex=3600)
r.set('0' * 40, "email:[email protected]", ex=3600)
def test_change_password(self):
c = Client()
payload = {'payload': json.dumps({'password': 'johnjohn'})}
url = '/reset/' + '0' * 40 + '/'
res = c.post(url, payload)
res = res.json()
self.assertEqual(res['password_changed'], True)
u = User.objects.get(username='john')
self.assertEqual(u.check_password('johnjohn'), True)
如果要使用selenium
IDE,请确保您是StaticLiveServerTestCase
固有的,而不是unittest.请遵循此示例.另外,不要忘记将变量self.base_url
更改为self.live_server_url
If you're going to use selenium
IDE, make sure you inherent from StaticLiveServerTestCase
instead of unittest. Follow this example. Also, don't forget to change this variable self.base_url
to self.live_server_url
这在我的setUp方法中
This inside my setUp method
self.base_url = self.live_server_url
感谢 Fips , koterpillar 在IRC频道上为我提供帮助, aks 在我的下方发表评论.
Thanks to fips, koterpillar for helping me on the IRC channel, and aks for commenting under me.
这篇关于无法在Django单元测试中测试密码更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!