gwift-book/source/part-3-django-concepts/unit_tests.adoc

4.9 KiB
Raw Blame History

Tests unitaires

Si on schématise linfrastructure et le chemin parcouru par une éventuelle requête, on devrait arriver à quelque chose de synthéthique:

  • Au niveau de linfrastructure,

    1. lutilisateur fait une requête via son navigateur (Firefox ou Chrome)

    2. le navigateur envoie une requête http, sa version, un verbe (GET, POST, …​), un port et éventuellement du contenu

    3. le firewall du serveur (Debian GNU/Linux, CentOS, …​) vérifie si la requête peut être prise en compte

    4. la requête est transmise à lapplication qui écoute sur le port (probablement 80 ou 443; et a priori Nginx)

    5. elle est ensuite transmise par socket et est prise en compte par Gunicorn

    6. qui la transmet ensuite à lun de ses workers (= un processus Python)

    7. après exécution, une réponse est renvoyée à lutilisateur.

architecture
  • Au niveau logiciel (la partie mise en subrillance ci-dessus), la requête arrive dans les mains du processus Python, qui doit encore

    1. effectuer le routage des données,

    2. trouver la bonne fonction à exécuter,

    3. récupérer les données depuis la base de données,

    4. effectuer le rendu ou la conversion des données,

    5. et renvoyer une réponse à lutilisateur.

django process

En gros, ça peut planter aux points suivants :

  1. Lutilisateur nest pas connecté à lInternet

  2. La version du navigateur utilisé est obsolète et les technologies de sécurité ne sont plus supportées

  3. La version dHTTP nest pas prise en charge par notre serveur

  4. Le verbe HTTP nest pas pris en charge par la fonction

  5. Le système na plus de place sur son disque

  6. Nginx est mal configuré

  7. La communication par socket est mal configurée

  8. LURL est inconnue

  9. La route nexiste pas

  10. La base de dnnées est inaccessible

  11. La fonction nest pas correctement appelée

  12. Il manque des valeurs au rendu

  13. Il y a tellement de données quNginx ou Gunicorn ou déjà envoyé une fin de requête à lutilisateur (timeout) …​

En bref, on a potentiellement un ou plusieurs problèmes potentiels à chaque intervenant. Une chose à la fois: dans un premier temps, on va se concentrer sur notre code.

Vous aurez remarqué ci-dessus quune nouvelle application créée par Django vient doffice avec un fichier tests.py. Cest simplement parce que les tests unitaires et tests dintégration font partie intégrante du cadre de travail. Ceci dit, chaque batterie de tests demande une certaine préparation et un certain "temps de cuisson"…​ Comprendre quun test ne sera effectif que sil est correctement structurée (configuration over convention ?), sil se trouve dans une classe et que chaque test se trouve bien dans une méthode de cette classe… Cela commence à faire beaucoup de boulot pour vérifier quune fonction retourne bien une certaine valeur, et en décourager la plupart dentrée de jeux, surtout quand on sait que chaque fonction, condition ou point dentrée sera sensée disposer de son test.

Au niveau des améliorations, on va :

  1. Changer de framework de test et utiliser pytest et son greffon pytest-django

  2. Ajouter une couverture de code.

Pytest

Pourquoi pytest, plutôt que Django ? Par pure fainéantise :-) Si, si ! Pytest est relativement plus facile à utiliser, permet un contrôle plus fin de certaines variables denvironnement et est surtout compatible hors-Django (en plus de quelques améliorations sur les performances, comme les tests sur plusieurs processus).

Cela signifie surtout que si vous apprenez Pytest maintenant, et que votre prochain projet est une application en CLI ou avec un autre framework, vous ne serez pas dépaysé. Les tests unitaires de Django sont compatibles uniquement avec Django… Doù une certaine perte de vélocité lorsquon devra sen détacher.

Vous trouverez ci-dessous une comparaison entre des tests avec les deux frameworks:

# avec django
# avec pytest

Plugins pytest :

Fixtures

Lien: super bien expliqué, et pourquoi les fixtures dans Pytest cest 'achement plus mieux que les tests unitaires de Django.

Couverture de code

Dans un premier temps, le pourcentage de code couvert par nos tests. Une fois ce pourcentage évalué, le but du jeu va consister à ce que ce pourcentage reste stable ou augmente. Si vous modifiez une ligne de code et que la couverture passe de 73% à 72%, vous avez perdu et vous devez faire en sorte de corriger.

Plein de trucs à compléter ici ;-) Est-ce quon passe par pytest ou par le framework intégré ? Quels sont les avantages de lun % à lautre ? * views.py pour définir ce que nous pouvons faire avec nos données.