thetalkingwalnut demande:
Quels sont les bons moyens de convaincre les développeurs sceptiques de l'équipe de la valeur des tests unitaires?
Tout le monde ici va accumuler de nombreuses raisons pour lesquelles les tests unitaires sont bons. Cependant, je trouve que souvent le meilleur moyen de convaincre quelqu'un de quelque chose est d' écouter son argumentation et de l'aborder point par point. Si vous les écoutez et les aidez à exprimer leurs préoccupations, vous pouvez les aborder et peut-être les convertir à votre point de vue (ou à tout le moins, les laisser sans jambe pour vous tenir debout). Qui sait? Peut-être qu'ils vous convaincront pourquoi les tests unitaires ne conviennent pas à votre situation. Peu probable, mais possible. Peut-être que si vous postez leurs arguments contre les tests unitaires, nous pouvons aider à identifier les contre-arguments.
Il est important d'écouter et de comprendre les deux côtés de l'argument. Si vous essayez d'adopter les tests unitaires avec trop de zèle sans tenir compte des préoccupations des gens, vous vous retrouverez avec une guerre de religion (et probablement des tests unitaires vraiment sans valeur). Si vous l'adoptez lentement et commencez par l'appliquer là où vous verrez le plus d'avantages au moindre coût, vous pourrez peut-être démontrer la valeur des tests unitaires et avoir une meilleure chance de convaincre les gens. Je me rends compte que ce n'est pas aussi facile qu'il y paraît - cela nécessite généralement un certain temps et des mesures minutieuses pour élaborer un argument convaincant.
Les tests unitaires sont un outil, comme tout autre, et doivent être appliqués de telle manière que les avantages (capture de bugs) l'emportent sur les coûts (l'effort de les écrire). Ne les utilisez pas si / où elles n'ont pas de sens et rappelez-vous qu'elles ne sont qu'une partie de votre arsenal d'outils (par exemple inspections, assertions, analyseurs de code, méthodes formelles, etc.). Ce que je dis à mes développeurs, c'est ceci:
Ils peuvent sauter la rédaction d'un test pour une méthode s'ils ont un bon argument pourquoi elle n'est pas nécessaire (par exemple trop simple pour en valoir la peine ou trop difficile pour en valoir la peine) et comment la méthode sera autrement vérifiée (par exemple, inspection, assertions , méthodes formelles, tests interactifs / d'intégration). Ils doivent considérer que certaines vérifications telles que les inspections et les preuves formelles sont effectuées à un moment donné, puis doivent être répétées à chaque fois que le code de production change, tandis que les tests unitaires et les assertions peuvent être utilisés comme tests de régression (écrits une fois et exécutés à plusieurs reprises par la suite. ). Parfois, je suis d'accord avec eux, mais le plus souvent, je vais débattre de savoir si une méthode est vraiment trop simple ou trop difficile à tester.
Si un développeur soutient qu'une méthode semble trop simple pour échouer, cela ne vaut-il pas la peine de prendre les 60 secondes nécessaires pour rédiger un simple test unitaire de 5 lignes? Ces 5 lignes de code s'exécuteront tous les soirs (vous effectuez des builds tous les soirs, non?) Pour l'année prochaine ou plus et en vaut la peine si même une seule fois il arrive à attraper un problème qui peut avoir pris 15 minutes ou plus à identifier et déboguer. En outre, l'écriture des tests unitaires faciles augmente le nombre de tests unitaires, ce qui donne au développeur une belle apparence.
D'un autre côté, si un développeur soutient qu'une méthode semble trop difficile à tester unitaire (ne vaut pas l'effort important requis), c'est peut-être une bonne indication que la méthode doit être divisée ou refactorisée pour tester les parties faciles. Habituellement, ce sont des méthodes qui s'appuient sur des ressources inhabituelles comme des singletons, l'heure actuelle ou des ressources externes comme un jeu de résultats de base de données. Ces méthodes doivent généralement être refactorisées en une méthode qui obtient la ressource (par exemple, appelle getTime ()) et une méthode qui prend la ressource en argument (par exemple, prend l'horodatage en paramètre). Je les laisse sauter le test de la méthode qui récupère la ressource et ils écrivent à la place un test unitaire pour la méthode qui prend maintenant la ressource en argument. Habituellement, cela rend l'écriture du test unitaire beaucoup plus simple et donc intéressante à écrire.
Le développeur doit tracer une "ligne dans le sable" dans la façon dont leurs tests unitaires devraient être complets. Plus tard dans le développement, chaque fois que nous trouvons un bogue, ils devraient déterminer si des tests unitaires plus complets auraient résolu le problème. Si tel est le cas et si de tels bogues surviennent à plusieurs reprises, ils doivent déplacer la "ligne" vers l'écriture de tests unitaires plus complets à l'avenir (en commençant par l'ajout ou l'extension du test unitaire pour le bogue actuel). Ils doivent trouver le bon équilibre.
Il est important de réaliser que les tests unitaires ne sont pas une solution miracle et qu'il existe trop de tests unitaires. Sur mon lieu de travail, chaque fois que nous faisons des leçons apprises, j'entends inévitablement "nous devons passer plus de tests unitaires". La direction hoche la tête en accord parce que ça leur a cogné la tête que "tests unitaires" == "bons".
Cependant, nous devons comprendre l'impact de «plus de tests unitaires». Un développeur ne peut écrire que ~ N lignes de code par semaine et vous devez déterminer quel pourcentage de ce code devrait être le code de test unitaire par rapport au code de production. Un lieu de travail laxiste peut avoir 10% du code en tant que tests unitaires et 90% du code en tant que code de production, résultant en un produit avec beaucoup de fonctionnalités (bien que très boguées) (pensez à MS Word). D'un autre côté, une boutique stricte avec 90% de tests unitaires et 10% de code de production aura un produit solide comme le roc avec très peu de fonctionnalités (pensez "vi"). Vous n'entendrez peut-être jamais des rapports sur le crash de ce dernier produit, mais cela a probablement autant à voir avec le produit qui ne se vend pas très bien qu'avec la qualité du code.
Pire encore, la seule certitude du développement logiciel est peut-être que "le changement est inévitable". Supposons que la boutique stricte (90% de tests unitaires / 10% de code de production) crée un produit qui a exactement 2 fonctionnalités (en supposant que 5% du code de production == 1 fonctionnalité). Si le client arrive et modifie 1 des fonctionnalités, ce changement supprime 50% du code (45% des tests unitaires et 5% du code de production). La boutique laxiste (10% tests unitaires / 90% code de production) a un produit avec 18 fonctionnalités, dont aucune ne fonctionne très bien. Leur client réorganise complètement les exigences pour 4 de leurs fonctionnalités. Même si le changement est 4 fois plus important, seulement la moitié de la base de code est mise à la poubelle (~ 25% = ~ 4,4% de tests unitaires + 20% du code de production).
Mon point est que vous devez communiquer que vous comprenez cet équilibre entre trop peu et trop de tests unitaires - essentiellement que vous avez réfléchi aux deux côtés du problème. Si vous pouvez convaincre vos pairs et / ou votre gestion de cela, vous gagnez en crédibilité et avez peut-être plus de chances de les gagner.