2016-05-04 2 views
0

Я пытаюсь написать тест интеграции приложения Django, чтобы проверить, был ли пароль изменен из API останова. Однако после вызова API смены пароля тестирование нового пароля не работает.Невозможно проверить смену пароля в Django unittest

Что я делаю здесь: изменить пароль к johnjohn через покоя вызова, то попробуйте проверить, если пароль действительно изменился

Мой UnitTest файл

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

Файл unittest называется rest_pass_login_tests.py в каталоге unittests.

Я запустил его, выполнив следующую команду.

./manage.py test unittests/ --pattern="rest_pass_login_tests.py"

Когда я проверяю обычно через браузер, смена пароля работает отлично. Однако, когда я пытаюсь проверить, был ли пароль изменен или нет с помощью unittest, я получаю неверный пароль.

Что я делаю неправильно?

+0

Почему вы не используете тестовый клиент django вместо urllib? – AKS

+0

Я использую селен, и я изменил код, чтобы использовать urllib.Тем не менее, вы правы насчет клиента django test – Ahmed

ответ

0

Вы не делаете http post, как ожидается ваше мнение.

Вот как сделать запись с помощью urllib2: Making a POST call instead of GET using urllib2

Но, так как вы уже используете requests модуль, почему не просто сделать:

url = 'http://127.0.0.1:8000/reset/' + '0' * 40 + '/' 
payload = {'csrfmiddlewaretoken': csrf_token, 'payload': json.dumps({'password': 'johnjohn'})} 
headers = {'Cookie': 'csrftoken=' + csrf_token} 
r = requests.post(url, data=payload, headers=headers) 
json_res = json.loads(r.content) 

А может быть, попробовать отладки/распечатывающих json_res в проверьте, есть ли что-нибудь еще неожиданное.

Также обратите внимание: это тест интеграции, который вы тестируете через http, поэтому ваши urls.py, views.py и даже settings.py проходят тестирование как часть этого.

+0

'' '[04/May/2016 03:18:48]« GET/reset/000000000000000000000000000000000000000000/HTTP/1.1 "200 3058 [04/May/2016 03:18: 48] "POST/reset/00000000000000000000000000000000000000000000/HTTP/1.1" 200 26 '' 'Нет, я делаю правильный пост. Тем не менее, я проверю ваш код – Ahmed

+0

'' '{u'password_changed ': True}' ''. У меня есть CBV и два метода: один для получения и один для сообщения. Я на 100% уверен, что он попал в сообщение. – Ahmed

+0

Я попытался выполнить тест E2E через селен, и у меня такая же проблема. Я удалил часть пользовательского интерфейса и начал выполнять только тест интеграции – Ahmed

1

Я использовал сервер dev для запуска unittests. Когда я изменил свой пароль, я фактически отправлял его на сервер dev вместо тестового.

Вот мой новый UnitTest

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. Следуйте за this example. Кроме того, не забудьте изменить эту переменную self.base_url в self.live_server_url

Этот внутри моего метода нАлАдкА

self.base_url = self.live_server_url

Благодаря fips, koterpillar за помощь мне на канале IRC, и aks для комментирования под меня ,

Смежные вопросы