Écrivez des tests pour votre API

 
Découvrez le TestCase de DRF

Les tests sont un élément important de tout projet de développement. Ils permettent de garantir la pérennité du projet, sa maintenance, et surtout de déployer la conscience plus tranquille.

Une nouvelle classe de test APITestCase  est fournie par DRF. Elle est faite pour fonctionner de la même façon que la classe TestCase. Sa principale différence étant d’utiliser un client qui permet une utilisation plus simple des appels. Il est donc recommandé de l’utiliser pour ne pas avoir à définir plusieurs paramètres pour réaliser nos appels lors des tests.

 
Écrivez des tests avec APITestCase

Créons notre fichier de test dans l’application shop  et mettons en place un test qui vérifie l’endpoint de récupération des catégories actives.

Nous allons pour cela :

  • Créer deux catégories dont une inactive ;

  • Réaliser notre appel ;

  • Vérifier que le status code de la réponse est bien un succès : 200 ; 

  • Nous assurer que le contenu de la réponse est bien celui attendu, et qu'il ne comprend pas la catégorie désactivée.

Nous écrirons aussi un test qui s’assurera que la création d’une catégorie n’est pas possible, et tombe bien en erreur.

Créons d'abord un fichier  tests.py  pour nos tests. Puis, c’est parti pour nos deux tests :

from django.urls import reverse_lazy
from rest_framework.test import APITestCase

from shop.models import Category

class TestCategory(APITestCase):
    # Nous stockons l’url de l'endpoint dans un attribut de classe pour pouvoir l’utiliser 
    # plus facilement dans chacun de nos tests
    url = reverse_lazy('category-list')

    def format_datetime(self, value):
        # Cette méthode est un helper permettant de formater une date en chaine de caractères sous le même format que celui de l’api
        return value.strftime("%Y-%m-%dT%H:%M:%S.%fZ")

    def test_list(self):
        # Créons deux catégories dont une seule est active
        category = Category.objects.create(name='Fruits', active=True)
        Category.objects.create(name='Légumes', active=False)

        # On réalise l’appel en GET en utilisant le client de la classe de test
        response = self.client.get(self.url)
        # Nous vérifions que le status code est bien 200 et que les valeurs retournées sont bien celles attendues
        self.assertEqual(response.status_code, 200)
        excepted = [
            {
                'id': category.pk,
                'name': category.name,
                'date_created': self.format_datetime(category.date_created),
                'date_updated': self.format_datetime(category.date_updated),
            }
        ]
        self.assertEqual(excepted, response.json())

    def test_create(self):
        # Nous vérifions qu’aucune catégorie n'existe avant de tenter d’en créer une
        self.assertFalse(Category.objects.exists())
        response = self.client.post(self.url, data={'name': 'Nouvelle catégorie'})
        # Vérifions que le status code est bien en erreur et nous empêche de créer une catégorie
        self.assertEqual(response.status_code, 405)
        # Enfin, vérifions qu'aucune nouvelle catégorie n’a été créée malgré le status code 405
        self.assertFalse(Category.objects.exists())

Suivez-moi dans le screencast ci-dessous pour la mise en place et le lancement de ces premiers tests.

 

En résumé
  • DRF met à disposition une classe de tests qu’il faut utiliser pour tester une API.

  • Il est important de tester le status code de retour ainsi que le contenu de la réponse.

  • Ne pas oublier de tester les cas d’erreur.

  • Les tests ne sont pas la partie la plus intéressante à écrire, mais ils garantissent la stabilité d’un projet dans le temps.

Nous voilà avec une API DRF simple et validée par nos premiers tests ! Avant de passer à l’étape suivante, validez vos acquis dans le quiz de la partie 1 – je vous attends dans la partie 2 !