Les tests Django : avis
Bonjour,
Avec le projet du mois j'ai décidé de vraiment me mettre aux Tests avec Django.
Dans l'app shop du repo ci-dessous il y a un package tests avec plusieurs fichiers. J'ai déjà bien avancé sur le test des urls et des vues. Les autres sont vides.
C'est un sacré pavé les tests, je suis en train de regarder des vidéos dessus.
C'est bien ce que j'ai fait jusqu'ici ? Car j'ai bien galéré sur le test test_create_garment_POST lol
https://github.com/gabigab117/docollective.git
Au passage, à la fin de mon test_views.py j'utilise pathlib et shutil pour supprimer un dossier test, car à chaque lancement de test ça me créer une image.
Merci d'avance
Salut Gab !
C'est super ça, tu avances bien 💪
Quelques points que j'ai noté en regardant ton code :
1) Pour la suppression de l'image, le problème actuellement c'est que si ton test échoue, l'image ne sera pas supprimée. Si tu as des opérations de nettoyage à faire après tes tests, utilise plutôt la méthode tearDown (l'inverse de setUp).
2) Dans test_create_garment_POST tu vérifies la redirection avec 302, c'est bien : mais vérifie aussi que ça redirige au bon endroit ;)
3) Tu peux aussi faire des tests pour vérifier ce qu'il se passe dans des scénarios non prévus par ton application. Par exemple : que se passe-t-il dans le cas où un utilisateur qui n'est pas authentifié essaie de créer un vêtement ? Est-ce que tu retournes une erreur, est-ce que tu le redirige vers la page de login.. ? Tu vas voir aussi en prenant l'habitude de faire ça que ça va te permettre en même temps d'améliorer ton code en prenant en compte des cas de figure que tu n'as pas prévu en créant l'application mais qui pourraient arriver (et comme ça tu es sûr qu'ils sont bien gérés comme tu le souhaite).
Pour ton image, tu peux créer un fichier en mémoire, ça t'évite d'avoir une dépendance sur disque. Tu peux le faire avec Pillow, ça donnerait quelque chose de ce genre :
from PIL import Image, ImageDraw
from io import BytesIO
from django.core.files.uploadedfile import SimpleUploadedFile
def create_test_image():
image = Image.new('RGB', (100, 100), color = 'white')
image_file = BytesIO() # Objet en mémoire
image.save(image_file, format='JPEG')
image_file.seek(0)
file_name = 'test_image.jpg'
uploaded_image = SimpleUploadedFile(name=file_name, content=image_file.getvalue(), content_type='image/jpeg')
return uploaded_image
Pour tearDown :
def tearDown(self):
folder_path = "mediafiles/test_gabigab"
if os.path.exists(folder_path):
shutil.rmtree(folder_path)
ça fonctionne donc ça c'est pas mal ?
Pour vérifier où je redirige
self.assertRedirects(response, reverse("index"), status_code=302)
Comme ça c'est bien ? Je vérifie le status et où je suis redirigé à la fois. Ou il faudrait mieux séparer les deux du style :
self.assertEquals(response.status_code, 302)
self.assertRedirects(response, reverse("index"))
Et si pas de login c'est ok je suis redirigé du coup (coucou le tuto Docshop lol) :
def test_create_garment_POST_no_login(self):
response = self.client.get(self.create_url)
self.assertEquals(response.status_code, 302)
self.assertRedirects(response, f"{reverse('accounts:login')}?next={reverse('shop:create')}")
Merci ! :)
Salut Gab !
Parfait pour le tearDown ! Essaie la méthode avec l'image en mémoire aussi, c'est plus "clean" ;)
Pour assertRedirects, ta deuxième proposition est en effet mieux. Il est préférable de séparer les deux tests, à savoir le statut de la réponse et la destination de la redirection, cela rend ton test plus clair. Comme ça si un jour il y a un souci, tu pourras rapidement voir si c'est à cause du statut de la redirection ou du lieu de la redirection.
Pour ce qui est du test de non-authentification, c'est super ! En fait, c'est justement ce genre de chose qu'il faut tester : que se passe-t-il si un utilisateur non authentifié tente d'accéder à telle ou telle fonctionnalité, et est-ce que ton application réagit bien comme prévu.
Le but des tests est de s'assurer que ton application se comporte bien comme tu l'attends, et cela peut inclure de nombreux scénarios différents comme ici :)
Inscris-toi
(c'est gratuit !)
Tu dois créer un compte pour participer aux discussions.
Créer un compte