Les Tests automatiques permettent, sans action manuelles rébarbatives de tester une application. Parmi ces tests figures les tests d’intégrations et un second type évoqué ici : les tests unitaires. Voici les bases théoriques.
Les Tests Unitaires sont un ensemble de test permettant de vérifier le bon fonctionnement d’une partie de l’application (d’une méthode bien souvent ; et donc d’une fonctionnalité). Un mode de développement, le Test Driven Développement, consiste même par commencé par imaginer le test à réaliser avant de développer la fonctionnalité correspondante.
Bases
On dit que les tests doivent être
- prédictif : L’exécution du test doit vérifier que le résultat est celui logiquement attendu par l’exécution de la fonctionnalité. Le test doit prédire que la fonctionnalité public
bool IsAdult(int age)renverra true siageest supérieur ou égal à 18 afin de vérifier le résultat retourné. - idempotent : L’exécution du test doit généré le même résultat quelque soit le nombre de fois qu’on l’exécute : il faut donc veiller à supprimer les éléments créer uniquement pour les besoins du test à la fin de ce dernier.
Afin de rester prédictif, pour des fonctionnalité issu de webservice indépendant de l’application (sensé renvoyé une température, un nombre de point…), des framework de simulacre tel Moq pourront être utilisé. L’idée est de vérifier qu’en cas de température supérieur à 25°, c’est bien un thermomètre rouge qui s’affiche sur notre application.
Le fait de renvoyer un résultat prédictif sur les fonctionnalité indépendante/variable est apeller « bouchonnage » de code. Toutefois on trouve les termes « doublure de tests » dont les « bouchons » et « simulacres » font partis, ainsi même que les « fantômes » et « substituts ».
Principes
Les tests représentant eux-même un coup en temps d’écriture, en temps de correction, de perfectionnement et d’évolution, il faut s’assurer d’écrire des tests utiles. Voici quelques principes à respecter :
1 : Montrer les regressions
Il ne faut pas tester des méthodes ou fonctionnalité qui font des manipulations de bases : opération de calcul simple (addition, soustraction etc.), comptage d’un nombre de caractères, incrémentation unique… Ces opérations sont des fonctionnalité de base de la programmations et n’ont aucune chance d’échouer : écrire un test pour cela élèverait surtout les cout de maintenance et s’apparente du coup surtout au fait de faire du zèle.
Il faut donc tester des fonctionnalité/méthode qui regroupe un nombre important de lignes et dont les régressions seraient probable dans le futur.
2 : Eviter les faux postif
Les Faux positifs sont les tests qui échouent tandis que le résultat renvoyé par la fonctionnalité est bon. Cela peut arriver lorsque le test se bornait à tester un détails d’une fonctionnalité qui a finit par évoluer. Ce principe est important : dans un équipe, plusieurs développeur peuvent être amené à faire tourner des tests et si l’un d’eux doit perdre du temps à comprendre pourquoi un test échoue alors qu’il sait que la fonctionnalité globale est bonne, le test va être ignoré et laissé à l’abandon (ce qui sera l’effet inverse de ce qui est attendu par les tests).
Il faut donc éviter de tester des détails de fonctionnalité amenés à changer, pour éviter d’avoir des tests déclenchant de fausse alarmes.
3 : Rapidité d’exécution
Les tests doivent être complet mais éviter de demander un temps de traitement trop important. L’intérêt d’un test est de rapidement détecter des régressions : s’il s’avère être trop long à exécuté, ils peuvent être ignoré par les développeur au profit d’une correction ultérieure.
Ecrire des tests courts, et privilégier les tests s’exécutant rapidement.
4 : Des tests simples
Afin d’éviter une trop lourde maintenance des tests, mieux vaut écrire de petit tests simples qu’un gros test complexe vérifiant tous les détails. En effet, ce dernier sera moins facile d’accès en cas d’echec (le développeur devra passer plus de temps à le comprendre) et demandera plus de temps à être corrigé si le résultat varie qu’à cause d’un refactoring de la fonctionnalité.
Alors que le fait d’éviter les faux positifs a comme intérêt d’éviter d’ignorer les tests (et donc qu’ils demeurent utile), réaliser des tests simples permet de limiter les coût de maintenance.
En se concentrant sur le résultat d’une fonctionnalité globale (en ignorant les traitements précis) un test court permet d’éviter de passer trop de temps à les modifier à chaque optimisation du code.
Sources
- https://openclassrooms.com/fr/courses/5641591-testez-votre-application-c/6777966-entrainez-vous-a-utiliser-les-tests-pour-detecter-un-probleme-dans-une-application
- Private : https://enterprisecraftsmanship.com/posts/unit-testing-private-methods/