Django fournit de nombreux outils de test; dans ce didacticiel, on utilisera certains d'entre eux pour tester une application avec un modèle d'utilisateur et une authentification personnalisés.
On va tester l'application userauth
qu'on a créée dans un didacticiel précédent. Il propose un modèle d'utilisateur personnalisé et une authentification avec allauth. La commande pour exécuter des tests pour une application ou un répertoire spécifique est:
python3 manage.py test userauth
L'argument test
est comparable à d'autres arguments utilisés par Django, tels que runserver
, createsuperuser
, migrate
etc. Vous pourriez obtenir l'erreur suivante:
Got an error creating the test database: permission denied to create database
C'est parce que Django créera une base de données de tests, qui sera détruite lorsque tous les tests auront été exécutés. Vous devez donc donner à l'utilisateur de la base de données l'autorisation de créer cette base de données de test. Accédez à l'invite de commande psql
:
psql postgres
et tapez la commande suivante:
ALTER USER usr_pet CREATEDB;
où usr_pet
est votre utilisateur de base de données. Sortez psql
avec \q
.
Une autre erreur pouvant survenir est:
ValueError: Missing staticfiles manifest entry for 'images/favicon-32x32.png'
ou quelque chose de similaire. Cela est dû à l'utilisation de ManifestStaticFilesStorage
dans le paramètre STATICFILES_STORAGE
dans nos paramètres. Django recommande de définir ce paramètre à sa valeur par défaut lors des tests, alors mettez une marque de commentaire devant la ligne où ce paramètre est défini.
Maintenant, si on exécute python3 manage.py test userauth
, Django vous dira combien de tests ont été exécutés et affichera toutes les erreurs. Même sans test, on peut toujours exécuter la commande test; Django passera par l'installation et fera d'autres choses, donc retournera OK ou détectera les erreurs s'il en a trouvé.
Il existe de nombreuses façons de tester et de nombreux articles sur ses limites. Deux méthodes de test populaires sont les tests de couverture (par exemple avec Coverage) et l'automatisation du navigateur (par exemple avec Selenium). Ici, on se limitera aux tests de couverture, qui peuvent être facilement intégrés à Django. Installez le package:
pip3 install coverage
Ajoutez-le à requirements.txt
et ajoutez coverage
à INSTALLED_APPS
. Exécutez-le avec:
coverage run --source=userauth manage.py test userauth
L'option source
indique à coverage
de mesurer seulement le code dans le répertoire userauth
, et le userauth
à la fin de la commande indique à Django d'exécuter uniquement les tests dans l'application userauth
. La commande suivante
coverage html
crée un répertoire htmlcov
dans le répertoire du projet avec un fichier index.html
dedans. Faites un clic droit dessus et choisissez open in browser
. Pour notre application userauth
, on voie qu'une partie substantielle du code est déjà visitée, même sans tests. En effet, dans notre application, on a utilisé au maximum les classes et méthodes intégrées de Django et allauth. Créons quelques tests pour les morceaux de code qui n'étaient pas couverts, en commençant par un simple: la représentation du modèle utilisateur personnalisé. Récapitulant de notre tutoriel précédent sur notre modèle d'utilisateur client:
def __str__(self):
return f"{self.username}: {self.first_name} {self.last_name}"
On utilisera la classe Testcase
de Django. On crée d'abord un utilisateur dans notre configuration avec setUpTestData
, puis on teste avec assertEqual
si la représentation est ce qu'elle devrait être:
from .models import CustomUser
from django.test import TestCase
class TestCustomUser(TestCase):
@classmethod
def setUpTestData(cls):
cls.user = CustomUser.objects.create(username="userJohnDoe", password="secretpassword", first_name="John", last_name="Doe")
def test_string_representation_of_customuser(self):
expected_representation_customuser = "userJohnDoe: John Doe"
self.assertEqual(expected_representation_customuser, str(self.user))
Exécuter coverage
à nouveau révélera qu'on a maintenant couvert ce morceau de code. Ceci est bien sûr un exemple très simple. Testons la méthode get_absolute_url
de notre modèle. Encore une fois à partir de notre tutoriel précédent:
def get_absolute_url(self):
return reverse('account_profile')
avec ce qui suit dans notre urls.py
:
path('profile/', profile_view, name='account_profile'),
et dans notre views.py
:
def profile_view(request):
return render(request, 'account/profile.html')
Un appel à profile_view
avec un utilisateur connecté doit donner une réponse valide. La documentation Django décrivent comment simuler une connexion utilisateur à l'aide de RequestFactory
, qui génère un objet de demande. On importe RequestFactory
et profile_view
:
from .views import profile_view
from django.test import RequestFactory
Dans notre setUpTestData
, on ajoute la ligne:
cls.factory = RequestFactory()
puis notre test est (en utilisant l'attribut status_code
de HttpResponse
):
def test_profile_view_with_user_gets_valid_response(self):
request = self.factory.get(self.user.get_absolute_url())
# log user in
request.user = self.user
self.assertEqual(profile_view(request).status_code, 200)
Notre test final pour userauth
sera sur LoginForm
dans forms.py
. Définissez un deuxième utilisateur dans setUpTestData
:
cls.user2 = CustomUser.objects.create(username="undefined", password="undefined", first_name="undefined", last_name="undefined")
On ne peut pas réutiliser le premier utilisateur, car les tests ne sont pas nécessairement exécutés dans l'ordre dans lequel ils sont définis, ce qui signifie que les changements dans un test pourraient affecter les variables réutilisées dans un autre. Définissez des données de formulaire, alimentez-les vers SignupForm
et utilisez la méthode signup
sur l'utilisateur nouvellement créé pour vérifier si la méthode fait ce qu'elle est censée faire:
def test_signup_form(self):
form_data = {'first_name': "Jane", 'last_name': "Doe", 'display_name': "Jane Doe"}
form = SignupForm(data=form_data)
self.assertTrue(form.is_valid())
form.signup(self, user=self.user2)
self.assertEqual(self.user2.display_name, "Jane Doe")
L'exécution répétée de coverage
montre qu'on a couvert plus de 95% du code de userauth
et que seules quelques lignes de code simples sont manquantes. On quitte les tests de cette application et continue.
Commentez cet article (connectez-vous d'abord ou confirmez par nom et email ci-dessous)