2010-04-14 4 views
5

J'écris des tests fonctionnels détaillés pour mes vues afin de compléter les tests unitaires sur mes modèles. C'est un projet Django et j'utilise le framework de test intégré de Django avec unittest. Évidemment, l'une des choses importantes à vérifier dans ces tests fonctionnels est que les autorisations sont correctement configurées. Dans cet esprit, je tente quelque chose comme ceci:Détection des erreurs d'autorisation dans les tests django

anonclient = Client() 
userclient = Client() 
userclient.login(username='test_user', password='test') 
adminclient = Client() 
adminclient.login(username='test_admin', password='test') 

path = "/path/to/my/page" 
anonresponse = anonclient.get(path) 
userresponse = userclient.get(path) 
adminresponse = adminclient.get(path) 

Je dois être en mesure de confirmer que le anonclient et userclient ont tous deux vu refuser l'autorisation alors que le AdminClient a fonctionné correctement. Howerver, je ne peux pas trouver un moyen de tester que cela est arrivé robuste! Au début, j'ai décidé de vérifier que la réponse était une redirection 302 (parce qu'un effet secondaire de la vérification d'autorisation est en cours de redirection), mais cela signifie qu'il est impossible de faire la différence entre la fonctionnalité qui redirige automatiquement l'utilisateur et vérification des autorisations échouée. (Je ne peux pas utiliser self.assertRedirects (response, url) car l'url cible peut être surchargé via le paramètre login_url de permission_required decorator dans la vue!)

Peut-être devrais-je envisager d'étendre le décorateur user_passes_test pour qu'il ajoute une propriété à l'objet de réponse si le test échoue? Cela pourrait ensuite être vérifié dans les tests. À défaut, je devrai déterminer si la demande a réussi en vérifiant si les effets secondaires de la demande se sont produits. Le faire de cette façon fonctionnera, mais il sera extrêmement long, surtout avec beaucoup de ces vérifications effectuées.

Je ne peux pas m'imaginer que je suis la première personne à rencontrer ce problème, quelle est la bonne façon de résoudre ce problème, ou qu'est-ce que j'ai manqué?

Merci beaucoup!

Répondre

1

Le client de test django renvoie un booléen lorsque vous appelez la méthode de connexion, qui vous indique si la connexion a réussi.

[17] >>> from django.test import Client 
[18] >>> c = Client() 
[19] >>> c.login(username='superuser', password='bar') 
[19] : False 
[20] >>> c.login(username='superuser', password='correct_password') 
[20] : True 
+0

Merci Justin, mais vous avez mal compris ma question - J'ai besoin de vérifier si le get suivant est réussi ou si une erreur d'autorisation se produit (avec redirection résultante). La connexion fonctionne correctement - je dois pouvoir tester que la vérification d'autorisation fonctionne sur la vue Django. – adamnfish

+0

Vous devriez être en mesure de vérifier si l'URL résultante est celle à laquelle vous avez essayé d'accéder. my_url = '/ foo /' resp = c.get (mon_url) Ensuite, vous pouvez vérifier l'objet '' resp'' pour les choses liées à votre page résultante. docs.djangoproject.com/fr/dev/topics/test/# testing-responses Spécifiquement, code d'état, vérification de l'utilisation du bon template, etc. –

+0

Comme je l'ai dit, j'aimerais pouvoir faire la différence entre une vue qui sert une redirection et une vue qui est redirigée par l'utilisateur qui échoue à un test. Je suis conscient que je peux vérifier les effets secondaires ou renifler la page résultante (en effet, c'est ce que je fais pour l'instant) mais je me demandais s'il y a un moyen de détecter que l'utilisateur a échoué un test et la vue courir, directement. Il semble qu'il n'y en a pas pour l'instant, donc je suppose que je vais soumettre une demande de fonctionnalité après la version 1.2 ou lancer moi-même un décorateur utilisateur_passes_test patché. – adamnfish

1

Le décorateur permission_required et PermissionRequiredMixin ont un paramètre raise_exception.

Une possibilité d'y faire face est d'avoir quelque chose comme une option de configuration PERMISSIONS_RAISE_EXCEPTION=True dans votre settings_test.py (si vous utilisez un des réglages séparés pour des séries de test et avez

from django.conf import settings 

@permission_required('<perm>', 
        raise_exception=settings.PERMISSIONS_RAISE_EXCEPTION) 
def your_view(...) 
    pass 

class YourView(PermissionRequired): 
    raise_exception = settings.PERMISSIONS_RAISE_EXCEPTION 

De cette façon, vous pouvez attraper le exception/test pour le 403 dans vos tests et conserver la redirection vers la page de connexion.

client.login('user', 'blah') 
response = client.get('/yourview') 
assertNot(403, response.status_code) 

Ajout du paramètre à tous vos permission_required décorateurs pourrait ne pas être à votre goût, il se sent un peu comme votre code de test ajouté dans votre source, mais c'est la seule façon que j'ai vu jusqu'à présent.

Questions connexes