Un des principes de l’agilité est de respecter la pyramide de tests, c’est à dire avoir une large base de tests unitaires automatisés. C’est même mis en lumière par une des pratiques promues à l’extrême par « extreme programming » (XP) : le TDD (Test Driven Development), le développeur doit écrire un test unitaire avant d’écrire la moindre ligne de code !
Mais c’est quoi un test unitaire ? Avez-vous déjà demandé à un développeur s’il fait des tests unitaires, il répond souvent par l’affirmative… puisqu’il teste (enfin quand il teste 😊) !
Un test fait par un développeur n’est pas obligatoirement un test unitaire, ne faites pas de sophisme, un test unitaire est bien un test fait par le développeur mais l’inverse n’est pas toujours vrai. Le niveau du test dépend de ce qui est testé, pas de qui teste… Aussi si votre développeur a besoin de déployer son application, ou passe des tests manuels, il n’est plus dans le domaine du test unitaire.
Un moyen mnémotechnique pour reconnaître un test unitaire : FIRST, c’est-à-dire (en tordant un peu le bras à la traduction) :
- Foudroyant (rapide) : S’exécute rapidement et est donc automatisé
- Isolé : Est indépendant des facteurs externes et des autres tests
- Répétable : Isole les bugs automatiquement
- Souverain (autonome) : N’est pas ambiguë (pas sujet à interprétation, ne demande pas une action manuelle pour vérifier le résultat)
- Tôt : Écrit en même temps que le code (même avant en TDD)
Si l’une de ces caractéristiques n’est pas respectée, il ne s’agit probablement pas d’un test unitaire.
Pour isoler les bugs automatiquement, un test unitaire doit tester le code unitairement, et isolement. Il doit donc être écrit dans le but de tester la logique d’une ligne de code, et quasiment si un test unitaire échoue vous pouvez connaitre la ligne de code incriminée.
Comme un test unitaire doit être isolé, il faut « simuler » (mocker) les composants qui ne sont pas les lignes de codes que vous testez. Ce qui est assez facile avec des bons principes de programmation (comme l’inversion de dépendance) mais peut s’avérer fastidieux, voir impossible si le code est mal écrit. D’où la nécessité de ne pas repousser l’écriture des tests unitaires, et même de les développer avant le code (TDD). En effet, le TDD entraine la testabilité de votre code, puisque vous avez écrit d’abord le test, le code est testable par construction. Grâce aux « mocks », un test unitaire n’a pas besoin d’un environnement pour être exécuté (si c’est le cas, il s’agit probablement d’un test d’intégration et non d’un test unitaire).
Si vous respectez ce principe, votre test unitaire a de grande chance d’être rapide, et de s’exécuter en quelques millisecondes. Cette rapidité devrait permettre de respecter un autre principe de XP : le build en moins de 10 minutes puisque vous pouvez passer des milliers de tests unitaires en quelques secondes seulement ! Cela fait un premier filet de sécurité contre la régression que le développeur peut aisément exécuter sur son poste (rapide et sans environnement) avant de « commiter » toutes modifications.
Certains développeurs ou chefs de projet (non informés, peu sensibilisés, etc…) argumenteront certainement que les tests unitaires coûtent chers, et qu’il n’y pas le budget nécessaire. Mais ceci est complètement faux, c’est même le contraire. D’expérience je peux vous assurer que les tests unitaires ont un retour sur investissement quasi immédiat et très positif. Si vous ne me croyez pas, je vous conseille de lire le livre « The Art of Unit Testing », dans lequel Roy Osherove raconte une expérience vécue sur un projet où il a comparé un développement avec et sans test unitaire. Les tests unitaires ne coûtent pas plus chers sur le développement complet (dans son expérience, seule « l’implémentation » coûte deux fois plus cher avec des tests unitaires, mais cela est largement compensé par les temps d’intégration, de test et de correction de bug), mais ils permettent d’avoir beaucoup moins de bugs en production (plus de 6 fois moins de bug dans l’expérience racontée)
Alors, pouvez vous vraiment vous offrir le luxe de ne pas avoir de (vrais) tests unitaires ?