L’auteur a choisi le Open Internet/Free Speech Fund pour recevoir un don dans le cadre du programme Write for Donations.
Il est presque impossible de construire des sites web qui fonctionnent parfaitement du premier coup sans erreurs. C’est pourquoi vous devez tester votre application web pour trouver ces erreurs et y remédier de manière proactive. Afin d’améliorer l’efficacité des tests, il est courant de décomposer les tests en unités qui testent des fonctionnalités spécifiques de l’application web. Cette pratique est appelée les tests unitaires. Il est plus facile de détecter les erreurs, car les tests se concentrent sur de petites parties (unités) de votre projet indépendamment des autres parties.
Tester un site web peut être une tâche complexe à entreprendre car il est constitué de plusieurs couches de logique comme le traitement des requêtes HTTP, la validation des formulaires et les modèles de rendu. Cependant, Django fournit un ensemble d’outils qui permettent de tester votre application web en toute transparence. Dans Django, la façon préférée d’écrire des tests est d’utiliser le module Python unittest
, bien qu’il soit possible d’utiliser d’autres cadres de test.
Dans ce tutoriel, vous allez mettre en place une suite de tests dans votre projet Django et écrire des tests unitaires pour les modèles et les vues de votre application. Vous effectuerez ces tests, analyserez leurs résultats et apprendrez comment trouver les causes des échecs.
Avant de commencer ce tutoriel, vous aurez besoin des éléments suivants :
Une séquence de tests dans Django est une collection de tous les scénarios de test de toutes les applications de votre projet. Pour permettre à l’utilitaire de test de Django de découvrir les scénarios de test que vous avez, vous écrivez les scénarios de test dans des scripts dont le nom commence par test
. Au cours de cette étape, vous allez créer la structure des répertoires et des fichiers de votre séquence de tests, et y créer un scénario de test vide.
Si vous avez suivi la série de tutoriels Django Development, vous aurez une application Django appelée blogsite
.
Créons un dossier pour contenir tous nos scripts de test. Tout d’abord, activez l’environnement virtuel :
- cd ~/my_blog_app
- . env/bin/activate
Ensuite, naviguez vers le répertoire appblogsite
, le dossier qui contient les fichiers models.py
et views.py
, puis créez un nouveau dossier appelé tests
:
- cd ~/my_blog_app/blog/blogsite
- mkdir tests
Ensuite, vous transformerez ce dossier en un paquet Python, ajoutez donc un fichier __init__.py
:
- cd ~/my_blog_app/blog/blogsite/tests
- touch __init__.py
Vous allez maintenant ajouter un fichier pour tester vos modèles et un autre pour tester vos vues :
- touch test_models.py
- touch test_views.py
Enfin, vous allez créer un scénario de test vide dans test_models.py
. Vous devrez importer la classe Django TestCase
et en faire une super classe de votre propre classe de test case. Plus tard, vous ajouterez des méthodes à ce scénario de test pour tester la logique de vos modèles. Ouvrez le fichier test_models.py
:
- nano test_models.py
Ajoutez maintenant le code suivant au fichier :
from django.test import TestCase
class ModelsTestCase(TestCase):
pass
Vous avez maintenant ajouté avec succès une séquence de tests à l’appli blogsite
. Ensuite, vous remplirez les détails du modèle de cas test vide que vous avez créé ici.
Dans cette étape, vous allez tester la logique du code écrit dans le fichier models.py
. En particulier, vous testerez la méthode de sauvegarde
du modèle Post
afin de vous assurer qu’il crée la bonne portion du titre d’un message lorsqu’il est appelé.
Commençons par regarder le code que vous avez déjà dans votre fichier models.py
pour la méthode de sauvegarde
du modèle Post
:
- cd ~/my_blog_app/blog/blogsite
- nano models.py
Vous verrez ce qui suit :
class Post(models.Model):
...
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
...
On peut voir qu’il vérifie si le message sur le point d’être sauvegardé a une valeur de slug, et si ce n’est pas le cas, il appelle slugify
pour lui créer une valeur de slug. C’est le type de logique que vous pourriez vouloir tester pour vous assurer que les slugs sont effectivement créés lors de la sauvegarde d’un message.
Fermez le dossier.
Pour le tester, retournez à test_models.py
:
- nano test_models.py
Mettez-le ensuite à jour en ajoutant les parties surlignées :
from django.test import TestCase
from django.template.defaultfilters import slugify
from blogsite.models import Post
class ModelsTestCase(TestCase):
def test_post_has_slug(self):
"""Posts are given slugs correctly when saving"""
post = Post.objects.create(title="My first post")
post.author = "John Doe"
post.save()
self.assertEqual(post.slug, slugify(post.title))
Cette nouvelle méthode test_post_has_slug
crée un nouvel article avec le titre « My first post »,
puis donne à l’article un auteur et l’enregistre. Ensuite, à l’aide de la méthode assertEqual
du module Python unittest
, il vérifie si le slug du message est correct. La méthode assertEqual
vérifie si les deux arguments qui lui sont transmis sont égaux tels que déterminés par l’opérateur « == »
et signale une erreur s’ils ne le sont pas.
Sauvegarder et quitter test_models.py
.
Voici un exemple de ce qui peut être testé. Plus vous ajoutez de logique à votre projet, plus il y a de choses à tester. Si vous ajoutez plus de logique à la méthode de sauvegarde
ou créez de nouvelles méthodes pour le modèle Post
, vous voudriez ajouter plus de tests ici. Vous pouvez les ajouter à la méthode test_post_has_slug
ou créer de nouvelles méthodes de test, mais leurs noms doivent commencer par test
.
Vous avez créé avec succès un cas test pour le modèle Post
où vous avez affirmé que les slugs sont correctement créés après la sauvegarde. Dans l’étape suivante, vous rédigerez un scénario de test pour tester les vues.
Dans cette étape, vous allez écrire un scénario de test qui teste une vue en utilisant le client de test Django. Le test client est une classe Python qui agit comme un navigateur web factice, vous permettant de tester vos vues et d’interagir avec votre application Django de la même manière qu’un utilisateur le ferait. Vous pouvez accéder au client test en vous référant à self.client
dans vos méthodes de test. Par exemple, créons un cas test dans test_views.py
Tout d’abord, ouvrez le fichier test_views.py
:
- nano test_views.py
Ajoutez ensuite ce qui suit :
from django.test import TestCase
class ViewsTestCase(TestCase):
def test_index_loads_properly(self):
"""The index page loads properly"""
response = self.client.get('your_server_ip:8000')
self.assertEqual(response.status_code, 200)
Le ViewsTestCase
contient une méthode test_index_loads_properly
qui utilise le client de test Django pour visiter la page d’index du site (http://your_server_ip:8000
, où your_server_ip
est l’adresse IP du serveur que vous utilisez). Ensuite, la méthode de test vérifie si la réponse a un code de statut de 200
, ce qui signifie que la page a répondu sans aucune erreur. Vous pouvez donc être sûr que lorsque l’utilisateur se rendra sur le site, il répondra lui aussi sans erreur.
Outre le code de statut, vous pouvez lire d’autres propriétés de la réponse du client de test que vous pouvez tester dans la page des réponses de test de la documentation de Django.
Au cours de cette étape, vous avez créé un scénario de test pour vérifier que la vue rendant la page d’index fonctionne sans erreur. Il y a maintenant deux scénarios de test dans votre séquence de tests. Au cours de l’étape suivante, vous les exécuterez pour voir leurs résultats.
Maintenant que vous avez terminé la construction d’une séquence de tests pour le projet, il est temps d’exécuter ces tests et de voir leurs résultats. Pour effectuer les tests, naviguez dans le dossier blog
(contenant le fichier manage.py
de l’application) :
- cd ~/my_blog_app/blog
Puis, exécutez-les :
- python manage.py test
Vous verrez un résultat similaire à ce qui suit dans votre terminal :
OutputCreating test database for alias 'default'...
System check identified no issues (0 silenced).
..
----------------------------------------------------------------------
Ran 2 tests in 0.007s
OK
Destroying test database for alias 'default'...
Dans cette sortie, il y a deux points ..
, dont chacun représente un cas de test réussi. Vous allez maintenant modifier test_views.py
pour déclencher un test d’échec. Ouvrez le fichier avec :
- nano test_views.py
Ensuite, changez le code en surbrillance pour :
from django.test import TestCase
class ViewsTestCase(TestCase):
def test_index_loads_properly(self):
"""The index page loads properly"""
response = self.client.get('your_server_ip:8000')
self.assertEqual(response.status_code, 404)
Ici, vous avez changé le code de statut de 200
à 404
. Maintenant, refaites le test à partir de votre répertoire avec manage.py
:
- python manage.py test
Vous verrez la sortie suivante :
OutputCreating test database for alias 'default'...
System check identified no issues (0 silenced).
.F
======================================================================
FAIL: test_index_loads_properly (blogsite.tests.test_views.ViewsTestCase)
The index page loads properly
----------------------------------------------------------------------
Traceback (most recent call last):
File "~/my_blog_app/blog/blogsite/tests/test_views.py", line 8, in test_index_loads_properly
self.assertEqual(response.status_code, 404)
AssertionError: 200 != 404
----------------------------------------------------------------------
Ran 2 tests in 0.007s
FAILED (failures=1)
Destroying test database for alias 'default'...
Vous voyez qu’il y a un message d’échec descriptif qui vous indique le script, le cas de test et la méthode qui a échoué. Il vous indique également la cause de l’échec, le code de statut n’étant pas égal à 404
dans ce cas, avec le message AssertionError: 200 ! 404
. L’AssertionError
est ici soulevée à la ligne de code surlignée dans le fichier test_views.py
:
from django.test import TestCase
class ViewsTestCase(TestCase):
def test_index_loads_properly(self):
"""The index page loads properly"""
response = self.client.get('your_server_ip:8000')
self.assertEqual(response.status_code, 404)
Il vous indique que l’affirmation est fausse, c’est-à-dire que le code de statut de réponse (200
) n’est pas ce à quoi on s’attendait (404
). Précédant le message d’échec, vous pouvez voir que les deux points ..
sont maintenant passés à . F
, qui vous indique que le premier cas test a réussi alors que le second ne l’a pas fait.
Dans ce tutoriel, vous avez créé une suite de tests dans votre projet Django, ajouté des scénarios de test au modèle de test et à la logique de visualisation, appris comment exécuter des tests et analysé les résultats des tests. Dans un deuxième temps, vous pouvez créer de nouveaux scripts de test pour le code Python qui n’est pas dansmodels.py
et views.py
.
Voici quelques articles qui peuvent s’avérer utiles pour créer et tester des sites web avec Django :
Vous pouvez également consulter notre page thématique sur Django pour d’autres tutoriels et projets.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!