python - login() en el marco de prueba de Django
testing authentication (2)
A menudo puede ser útil usar un back-end de autenticación personalizado que evite cualquier tipo de autenticación durante la prueba:
from django.contrib.auth import get_user_model
class TestcaseUserBackend(object):
def authenticate(self, testcase_user=None):
return testcase_user
def get_user(self, user_id):
User = get_user_model()
return User.objects.get(pk=user_id)
Luego, durante las pruebas, agregue yourapp.auth_backends.TestcaseUserBackend
a su AUTHENTICATION_BACKENDS
:
AUTHENTICATION_BACKENDS = [
"akindi.testing.auth_backends.TestcaseUserBackend",
]
Luego, durante las pruebas, simplemente puede llamar:
from django.contrib.auth import login
user = User.objects.get(…)
login(testcase_user=user)
Empecé a usar el framework de pruebas de Django, y todo funcionaba bien hasta que comencé a probar páginas autenticadas.
En aras de la simplicidad, digamos que esta es una prueba:
class SimpleTest(TestCase):
def setUp(self):
user = User.objects.create_user(''temporary'', ''[email protected]'', ''temporary'')
def test_secure_page(self):
c = Client()
print c.login(username=''temporary'', password=''temporary'')
response = c.get(''/users/secure/'', follow=True)
user = User.objects.get(username=''temporary'')
self.assertEqual(response.context[''email''], ''[email protected]'')
Después de ejecutar esta prueba, falla, y veo que el valor de retorno de la impresión de login () devuelve True , pero response.content se redirige a la página de inicio de sesión (si el inicio de sesión falla, el decorador de autenticación redirige a la página de inicio de sesión). He puesto un punto de quiebre en el decorador que hace la autenticación:
def authenticate(user):
if user.is_authenticated():
return True
return False
y realmente devuelve False . La línea 4 en test_secure_page () recupera correctamente al usuario.
Esta es la función de vista:
@user_passes_test(authenticate, login_url=''/users/login'')
def secure(request):
user = request.user
return render_to_response(''secure.html'', {''email'': user.email})
Por supuesto, si trato de iniciar sesión a través de la aplicación (fuera de la prueba), todo funciona bien.
El problema es que no está pasando RequestContext
a su plantilla.
Además, probablemente deba usar el decorador login_required
y el cliente integrado en la clase TestCase
.
Lo volvería a escribir así:
#views.py
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from django.contrib.auth import get_user_model
@login_required(login_url=''/users/login'')
def secure(request):
user = request.user
return render(request, ''secure.html'', {''email'': user.email})
#tests.py
class SimpleTest(TestCase):
def setUp(self):
User = get_user_model()
user = User.objects.create_user(''temporary'', ''[email protected]'', ''temporary'')
def test_secure_page(self):
User = get_user_model()
self.client.login(username=''temporary'', password=''temporary'')
response = self.client.get(''/manufacturers/'', follow=True)
user = User.objects.get(username=''temporary'')
self.assertEqual(response.context[''email''], ''[email protected]'')