Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ajoute un guide dans la doc sur l'écriture de tests back #6167

Merged
1 change: 1 addition & 0 deletions doc/source/guides.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ Guides pas-à-pas
guides/update-env.rst
guides/run-linux.rst
guides/backend-tests.rst
guides/write-backend-tests.rst

.. include:: /includes/contact-us.rst
2 changes: 2 additions & 0 deletions doc/source/guides/backend-tests.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,5 @@ Il suffit alors de remonter la sortie de la console et chercher des lignes de la
Il ne vous reste alors plus qu'à corriger votre code ou mettre à jour les tests concernés. :-)

Pour en savoir plus sur les tests avec Django, consultez la `documentation officielle <https://docs.djangoproject.com/en/dev/topics/testing/overview/>`_.

Pour en savoir plus sur l'écriture de tests *backend* pour Zeste de Savoir, consultez le `guide correspondant <./write-backend-tests.html>`_.
94 changes: 94 additions & 0 deletions doc/source/guides/write-backend-tests.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
==================================
Écrire des tests pour le *backend*
==================================

Zeste de Savoir aspire à avoir une base de code aussi qualitative et maintenable que possible, notamment grâce à une suite de tests automatisés pour le *backend* Python. Lorsqu'on développe pour Zeste de Savoir, on est ainsi amené à modifier cette suite de tests et ainsi contribuer à la qualité du code.

Ce guide est destiné aux contributeurs qui recherchent des conseils pour la mise en œuvre des tests *backend* sur Zeste de Savoir. Si vous souhaitez simplement lancer les tests existants, référez-vous au `guide correspondant <./backend-tests.html>`_.

Comprendre la politique de tests
================================

La politique actuelle pour les tests du *backend* est que tout ce qui est écrit en Python doit être testé. Ce n'est pas entièrement le cas actuellement, mais c'est l'objectif vers lequel on tend.

En conséquence, toute mise à jour du code doit s'accompagner de la création (ou adaptation) de tests pour au minimum couvrir le comportement ajouté ou modifié. L'ajout de tests manquants mais hors du périmètre de la modification n'est pas requis.

La présence de tests adéquats est vérifiée lors de l'assurance qualité des PR. Toute fusion de PR sans tests associés est exceptionnelle et cantonnée à des situations où la balance bénéfices-risques est acceptable. Accepter une PR sans tests associés est laissé à l'appréciation de l'équipe qui fusionne les PR.

Les contributions destinées purement à l'amélioration des tests sont les bienvenues. En effet, l'historique du projet fait que certaines parties du projet sont peu, mal, ou pas testées automatiquement.

Quoi qu'il en soit, l'équipe est disponible sur le canal ``#dev-de-zds`` de `notre serveur Discord <https://discord.gg/ue5MTKq>`_ ou `le forum Dev Zone <https://zestedesavoir.com/forums/communaute/dev-zone/>`_ pour vous aider si vous avez des doutes, questions ou difficultés.
philippemilink marked this conversation as resolved.
Show resolved Hide resolved


Identifier ce qu'il faut tester
===============================

Avant d'écrire des tests, il est important d'identifier précisément ce que l'on teste. Cette question peut paraître triviale, mais est pourtant primordiale, car cela change la manière dont les tests seront écrits, les efforts pour ce faire et leur valeur ajoutée.

Quelles sont les limites de la chose testée ?
---------------------------------------------

Il faut être en mesure de délimiter précisément la chose testée, en précisant son interface (au sens large) : quelles sont les entrées, les sorties, et être capable de relier les unes aux autres.

Par exemple pour une fonction, les entrées incluent naturellement les arguments de la fonction et les sorties les valeurs de retour. Cependant, si la fonction lit ou modifie un état (attributs d'objet, base de données, fichiers), alors les entrées incluent aussi les états initiaux et les sorties les états finaux.

Les entrées et sorties peuvent être des choses complexes. Par contre, si vous n'êtes pas capable de les identifier clairement, c'est peut-être dû à une mauvaise conception de ce que vous souhaitez tester. Essayez de restructurer vos changements !

Est-ce que les limites identifiées sont les bonnes ?
----------------------------------------------------

Maintenant que vous avez identifié des limites pour la chose à tester, questionnez-vous sur leur pertinence. Les exemples ci-dessous listent quelques écueils qui peuvent survenir en pratique.

**Tester le code du framework au lieu du sien.** Avec Django, on réutilise des classes de base fournies par le *framework*. Il est assez facile de retester des comportements déjà vérifiés par la classe en question. Par exemple, si vous utilisez des *templates views*, il n'est pas nécessaire en général de tester automatiquement que le template que vous avez indiqué est bien celui utilisé : c'est à Django de vérifier que la classe fonctionne correctement. C'est d'ailleurs un risque de faire des tests redondants avec le code et donc plus difficile à maintenir dans la durée.
philippemilink marked this conversation as resolved.
Show resolved Hide resolved

**Étendre excessivement le périmètre du test.** Quand on définit l'interface du code à tester, on peut parfois voir grand. Par exemple, on peut être tenté pour une vue de faire un test en regardant dans le rendu HTML si les informations attendues sont présentées comme prévu. Ce faisant, on teste le rendu du template en plus de la vue. Ce n'est pas forcément pertinent, donc réfléchissez bien à restreindre vos interfaces si vous pensez avoir vu trop large.
philippemilink marked this conversation as resolved.
Show resolved Hide resolved


Organiser les tests
===================

Cette section donne quelques conseils généraux pour vous aider à organiser vos tests.

Séparer les niveaux d'abstraction
---------------------------------

On peut se retrouver à tout vouloir tester en même temps : les droits d'accès, les redirections,
le comportement dans différentes situations, etc. Pour faciliter les tests, considérez de séparer suivant différents aspects :

* les droits d'accès peuvent souvent être vérifiés sans aucunement tester le fonctionnel (erreur ou pas d'erreur) ;
* les redirections peuvent se vérifier souvent indépendamment du fonctionnel (redirigé ou non) ;
* le fonctionnel n'a par exemple pas besoin de s'entremêler avec la gestion des droits dans de nombreux cas.

On peut observer un découpage dans cet esprit dans ``./zds/tutorialv2/tests/tests_views/tests_editcontentlicense.py``.

Éviter les duplications
-----------------------

Quand on teste différents résultats attendus pour différentes entrées, on peut être amené à écrire du code qui a tendance à se répéter. Si tel est le cas, une bonne stratégie consiste à décrire les cas de tests sous forme de données (par exemple à l'aide d'un dictionnaire) et ensuite écrire une unique fonction de tests qui jouera tous les différents cas en appliquant la même logique à chaque fois.

Cette technique est par exemple employée dans ``./zds/tutorialv2/tests/tests_views/tests_editcontentlicense.py``.

Découper en fichiers
--------------------

Les fichiers de tests sur Zeste de Savoir sont historiquement assez longs, et peuvent atteindre plusieurs centaines voire plusieurs milliers de lignes. Mais ce n'est pas vraiment une bonne idée !

Si vous êtes amenés à rajouter plusieurs centaines de lignes de tests dans un fichier (ce qui est vite arrivé dans certains cas), considérez le choix de faire un fichier séparé.


Connaître les outils pratiques
==============================

Quelques lectures en lien avec Django :

* `l'aperçu global des tests avec Django <https://docs.djangoproject.com/en/2.2/topics/testing/overview/>`_ ;
* `la documentation sur les outils de test fournis par Django <https://docs.djangoproject.com/en/2.2/topics/testing/tools/>`_.

Une tâche qui revient très souvent lors des tests est la création d'utilisateurs, sujets de forum, messages, tutoriels, articles, etc.
Il existe des outils de développement pour faciliter leur création appelés *Factory* et qu'on retrouve dans les fichiers `factories.py` de chaque module. L'usage est simple, il suffit d'appeler le constructeur pour recevoir un objet du type souhaité :

.. sourcecode:: python

self.author = ProfileFactory() # self.author est un objet Profile !

.. include:: /includes/contact-us.rst
Arnaud-D marked this conversation as resolved.
Show resolved Hide resolved