JUnit
JUnit est un framework de tests unitaires pour le langage Java créé par Kent Beck et Erich Gamma. Les tests unitaires permettent de vérifier si le comportement de chaque méthode de chaque classe Java est bien celui désiré en fonction des entrées que l'on soumet (jeux de test/scénario).
JUnit fournit donc un cadre de développement et d'exécution pour ce type de tests.
JUnit est particulièrement adapté aux développeurs souhaitant faire du développement dirigé par les tests (Tests Driven Development) dont la particularité majeure est de développer le test unitaire avant le code lui-même. On décrit donc, par l'écriture d'un test unitaire, le comportement attendu d'une classe et ce n'est qu'à partir de ce moment que l'on commence à écrire le code de cette classe de façon à ce qu'elle passe le test. Si les tests sont correctement écrits et complets, on s'assure donc de développer des classes sans erreurs et répondant exactement à nos besoins.
JUnit est également un outil particulièrement utile pour réaliser des tests de non-régressions du fait qu'il permet d'avoir des tests automatisés et rejouables. En ré-exécutant les suites de tests après une correction, une modification ou une évolution du code, on peut s'assurer qu'il n'y a pas eu d'effets de bords sur le comportement du logiciel qui était déjà codé.
Enfin, on peut noter que la mise en place de tests unitaires permet d'améliorer les conditions de "transmissibilité" d'un code du développeur/auteur vers un autre développeur, en sécurisant les interventions d'un novice dans le code : cette démarche participe à un apport organisationnel, libérant, dans une certaine mesure, le développeur/auteur des tâches de maintenance.
Il existe des tâches Ant permettant d'exécuter les tests et d'écrire les résultats dans des fichiers XML pour générer des rapports HTML présentant les résultats des tests.
Il existe aussi un plugin Maven pour générer ce type de rapports.
JUnit a été porté dans d'autre langage :
Ada (AUnit)
C# (NUnit)
C++ (CPPUnit)
Fortran (fUnit)
Delphi (DUnit)
Free Pascal (FPCUnit)
JavaScript (JSUnit)
Objective-C (OCUnit)
Perl (Test::Class and Test::Unit)
PHP (PHPUnit)
Python (PyUnit)
R (RUnit)
Haskell (HUnit)
Nous utilisons JUnit à travers le plugin Eclipse pour l'écriture de tests pour des applications Java (Web ou non) majoritairement pour des classes déjà existantes (très peu de développement dirigé par les tests).
L'utilisation de tests unitaires est un énorme atout pour le développement de logiciels de meilleure qualité. Cependant, l'utilisation de ce type d'outil ne garantit en aucun cas que le logiciel est complètement testé et qu'aucun bug n'est présent. En particulier, JUnit ne permet pas de réaliser :
- Les tests d'intégration
- Les tests fonctionnels
- Les tests de couverture de code
- Les tests de montée en charge
Il ne permet pas non plus de séparer les jeux de données des tests eux-mêmes.
D'autres outils (libres et commerciaux) existent sur le marché pour ce type de test.
L'écriture et l'exécution des tests unitaires lors d'un développement, que les tests soient écrits avant ou après le codage des classes, représente une charge de travail non-négligeable. Il y a encore souvent débat pour savoir si le temps passé à développer les tests unitaires est réellement justifié par un nombre suffisamment important de bugs détectés par ce moyen.
Cependant, on sait que plus les bugs sont détectés tardivement, plus ils sont difficiles et coûteux à corriger. Les tests unitaires présentent l'avantage indéniable de permettre une détection anticipée des bugs, donc une correction plus précoce, et par conséquent un gain sur le coût de la correction. Donc, si on s'interroge sur le rapport entre le temps passé à corriger des bugs tardivement dans un projet et le temps passé à les corriger quand ils sont détectés très tôt, on peut dire que les tests unitaires donnent de bons résultats (sans tenir compte de leurs nombreux autres avantages...).
La mise en œuvre précoce de tests unitaires est particulièrement bien adaptée à une approche "Test Driven Development". Pour les autres approches, l'utilisation des tests unitaires devrait se faire par rapport au besoin identifié : par exemple partage de code, sécurisation d'un changement important de code, clôture d'une phase du projet, .....