web-dev-qa-db-fra.com

login () dans le framework de test Django

J'ai commencé à utiliser le framework de test de Django et tout fonctionnait bien jusqu'à ce que je teste des pages authentifiées.

Par souci de simplicité, disons qu'il s'agit d'un test:

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]')

Après avoir exécuté ce test, il échoue et je constate que l'impression de la valeur renvoyée par login () renvoie True , mais response.content est redirigé vers la page de connexion (en cas d'échec de la connexion, le décorateur redirige vers la page de connexion. ). J'ai mis un point d'arrêt dans le décorateur qui effectue l'authentification:

def authenticate(user):
    if user.is_authenticated():
        return True
    return False

et il revient vraiment Faux . La ligne 4 de test_secure_page () récupère correctement l'utilisateur.

C'est la fonction de vue:

@user_passes_test(authenticate, login_url='/users/login')
def secure(request):
    user = request.user
    return render_to_response('secure.html', {'email': user.email})

Bien sûr, si j'essaie de me connecter via l'application (en dehors du test), tout se passe bien.

28
kevin

Le problème est que vous ne passez pas RequestContext à votre modèle. 

En outre, vous devriez probablement utiliser le décorateur login_required et le client construit dans la classe TestCase.

Je le récrirais comme ceci:

#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]')
27
Filip Jukić

Il peut souvent être utile d’utiliser un système d’authentification personnalisé qui contourne toute sorte d’authentification lors des tests:

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)

Ensuite, pendant les tests, ajoutez yourapp.auth_backends.TestcaseUserBackend à votre AUTHENTICATION_BACKENDS:

AUTHENTICATION_BACKENDS = [
    "akindi.testing.auth_backends.TestcaseUserBackend",
]

Ensuite, pendant les tests, vous pouvez simplement appeler:

from Django.contrib.auth import login
user = User.objects.get(…)
login(testcase_user=user)
11
David Wolever

Authentification basée sur les jetons: J'étais dans la même situation.J'ai trouvé un sloution dans lequel j'ai effectivement créé un utilisateur pour la connexion dans la méthode setUp. demander des données.

installer:

1> créer un utilisateur Ex.
self.pravesh = User.objects.create(email='[email protected]',first_name='Pravesh',last_name='aaabbb',phone='5456165156',phonecountrycode='91')  

2> définir le mot de passe pour l'utilisateur

méthode d'essai:  

1> créer un client
ex.
client.login(email=self.pravesh.email, password=self.password)

2> obtenir un jeton (en cas d’autorisation de jeton) Ex
token = Token.objects.create(user=self.pravesh) 

2> transmettre les informations de connexion Ex 

`response = client.post(
        reverse('account:post-data'),
        data = json.dumps(self.data),
        HTTP_AUTHORIZATION='Token {}'.format(token),
        content_type = 'application/json'
    )`    
0
OpenHub