Les tests unitaires ou le développement dirigé par les tests en valent-ils la peine?

48

Mon équipe au travail passe à Scrum et d’autres équipes commencent à faire du développement piloté par les tests en utilisant des tests unitaires et des tests d’acceptation des utilisateurs. J'aime les UAT, mais je ne suis pas vendu aux tests unitaires pour le développement piloté par les tests ou le développement piloté par les tests en général.

Il semble que l'écriture de tests représente un travail supplémentaire, donne aux gens une béquille quand ils écrivent le code réel, et pourrait ne pas être efficace très souvent.

Je comprends comment fonctionnent les tests unitaires et comment les écrire, mais est-ce que quelqu'un peut affirmer que c'est vraiment une bonne idée et que cela en vaut la peine?

De plus, y a-t-il quelque chose qui rend TDD particulièrement bon pour Scrum?

Owen Johnson
la source
27
Si vous souhaitez vous assurer que votre logiciel tombe souvent en panne, qu'il est plus ou moins complètement immuable, et qu'il doit être remplacé avant qu'il ne soit prêt pour la production. alors je vous suggérerais de vous dispenser complètement des tests unitaires et de ne jamais prendre le temps d'apprendre le TDD.
Dawood dit réintégrer Monica
3
Pensez au souhait / besoin d'un refactor. Seriez-vous plus confiant dans la refactorisation (de toute ampleur) avec ou sans un ensemble complet de tests unitaires pour vous attraper lorsque vous avez cassé quelque chose par inadvertance?
Marjan Venema
2
"Donne aux gens une béquille quand ils écrivent du vrai code"? La plupart des meilleures pratiques ne peuvent-elles pas être décrites de cette façon?
user16764
4
@ DavidWallace: C'est le problème des développeurs incompétents, pas un manque de TDD. De plus, même lorsque TDD est utilisé à grande échelle, cela ne donne aucune garantie que les modifications que vous avez apportées ne brisent rien.
Codeur
6
@NimChimpsky: Je n'ai aucune négativité envers le TDD, je ne suis tout simplement pas à la mode. Il a ses côtés positifs et négatifs également. Faux sentiment de sécurité étant l'un d'entre eux.
Codeur

Réponses:

69

Réponse courte: Absolument positif.

Réponse longue: Les tests unitaires sont l’une des pratiques les plus importantes que j’essaie d’influencer sur mon lieu de travail (grande banque, trading fx). Oui, c’est un travail supplémentaire, mais c’est un travail qui rapporte sans cesse. Les tests unitaires automatisés vous aident non seulement à exécuter le code que vous écrivez et bien sûr à vérifier vos attentes, mais ils agissent également comme une sorte de chien de garde pour les modifications futures que vous-même ou quelqu'un d'autre pourrait apporter. Il y aura rupture du test lorsque quelqu'un modifiera le code de manière indésirable. Je pense que la valeur relative des tests unitaires diminue en corrélation avec le niveau de changement et la croissance attendus dans une base de code, mais la vérification initiale de ce que le code rend vaut la peine, même lorsque le changement attendu est faible. La valeur du test unitaire dépend également du coût des défauts. Si le coût d'un défaut est égal à zéro (la perte de temps / d'argent, de réputation / d'effort futur) est égal à zéro, la valeur relative d'un test est également égale à zéro; Cependant, ce n'est presque jamais le cas dans un environnement commercial.

En général, nous n'embauchons plus de personnes qui ne créent pas systématiquement de tests unitaires dans le cadre de leur travail - c'est simplement quelque chose que nous attendons, comme arriver tous les jours. Je n'ai pas vu d'analyse coûts-avantages purement avoir des tests unitaires (quelqu'un se sent libre de m'orienter vers un test), mais je peux dire d'expérience que dans un environnement commercial, pouvoir prouver que le code fonctionne dans un grand système important en vaut la peine . Cela me permet également de mieux dormir la nuit, sachant que le code que j'ai écrit fonctionne de manière prouvée (jusqu'à un certain niveau) et que, si cela change, quelqu'un sera averti des effets secondaires inattendus par une construction endommagée.

Le développement piloté par les tests, dans mon esprit, n'est pas une approche de test. Il s’agit en fait d’une approche / pratique de conception dont le résultat est le système opérationnel et un ensemble de tests unitaires. Je suis moins religieux à propos de cette pratique car c'est une compétence assez difficile à développer et à perfectionner. Personnellement, si je construis un système et que je ne sais pas comment cela va fonctionner, j'emploierai le TDD pour m'aider à trouver mon chemin dans le noir. Cependant, si j'applique un modèle / une solution existante, ce n'est généralement pas le cas.

En l’absence de preuve mathématique selon laquelle il est utile d’écrire des tests unitaires, je vous encourage à l’essayer sur une longue période et à en profiter vous-même.

rupjones
la source
5
Ce que j'aimerais ajouter, c'est que les tests unitaires vous font également penser à la conception de votre interface. Quand vous arrivez à une partie où vous pensez "comment puis-je tester les méthodes privées?", Vous savez que votre interface est probablement fausse.
TC1
1
"Je vous encourage à l'essayer pendant une période prolongée et à en profiter vous-même." Essayer de le faire une fois me suffisait, les avantages semblaient évidents.
NimChimpsky
1
+1 pour "Nous n'embauchons généralement plus de personnes qui ne créent pas systématiquement de tests unitaires dans le cadre de leur travail". J'ai récemment dû rejeter un candidat qui, parmi d'autres lacunes, avait fermement proclamé qu'il n'aimait pas écrire des tests automatiques, car ils constituaient une perte de temps et qu'il pouvait tester le code lui-même.
ftr
4
vous ne pouvez pas prouver qu'un code non trivial fonctionne de manière pertinente en utilisant simplement des tests automatisés. Avec des tests automatisés, vous ne pouvez que prouver que le code réussit les tests . Si les tests couvrent 100% de vos cas d'utilisation, vous avez votre "certain niveau" probablement, mais cela ne signifie toujours pas que le code "fonctionne de manière vérifiable". Avoir un vrai prouvable, vous auriez besoin en.wikipedia.org/wiki/Formal_verification - en tant que tel, vous utilisez le terme « démontrable » ne va pas ici.
vaxquis
1
@vaxquis Oui, vous avez absolument raison d'utiliser le terme preuve. Mais je parierais que la présence de tests (ou la pratique du TDD) est une meilleure preuve du bon fonctionnement d'un système que l'absence de tests.
Rupjones
16

Les erreurs trouvées plus tôt sont moins coûteuses à corriger que les erreurs trouvées plus tard. TDD vous aide à vérifier l'exactitude de votre système. Vous investissez un peu plus tôt, mais vous le récupérez plus tard. Le graphique est un peu exagéré, mais il montre bien l'idée.

entrez la description de l'image ici

Source de l'image

Martin Wickman
la source
Qu'entendez-vous par traditionnel ? Quelque chose qui n'est pas TDD?
Giorgio
Il ne semble pas que ce graphique soit basé sur des statistiques réelles, il ne représente que l'expérience d'une seule personne qui a écrit cette entrée de blog en 2006. Ce n'est pas que je dise que c'est totalement faux, mais la réalité est bien plus compliquée.
Doc Brown le
9

Les tests unitaires ou le développement piloté par les tests en valent-ils la peine?

Oui c'est le cas . Oncle Bob (Robert C. Martin) a raconté dans une présentation;

Pour qu'un développeur prouve que son code fonctionne mieux, il écrit un test et le réussit plutôt que de crier, de chanter ou de danser à ce sujet.

Et puisque vous n'allez pas supprimer le test, tant que le test est une réussite, vous êtes certain que la fonctionnalité fonctionne - les problèmes de régression sont résolus.

Il y a beaucoup de choses écrites dessus,

  1. Vous êtes responsable de faire fonctionner cette fonctionnalité. Ecrivez un test. Simplement fais-le.
  2. Quand remplacer les tests unitaires par le test d'intégration

Le SCRUM, les tests unitaires et le TDD sont-ils liés?

Bientôt, lorsque vous serez maître, Unit testingvous serez proche de TDD. SCRUM n’a rien à voir avec cela, mais comme on dit, de grandes choses se mélangent bien, ces techniques de développement d’un logiciel s’ajoutent à une excellente pile , si vous ne l’avez pas encore essayé, essayez-le.

Y a-t-il quelque chose qui rend le TDD particulièrement bon pour SCRUM?

Comme je l'ai dit plus haut, ils font un bon mariage . Si vous y ajoutez des tests d’automatisation, c’est plus spécial .

ManuPK
la source
8

Il semble que l'écriture de tests représente un travail supplémentaire, donne aux gens une béquille quand ils écrivent le code réel, et pourrait ne pas être efficace très souvent.

Les tests unitaires ont de la valeur en tant que béquille. Il soutient vos efforts de développement en vous permettant de modifier votre implémentation sans craindre que votre application cesse de fonctionner correctement. Les tests unitaires sont aussi beaucoup plus qu'une simple béquille, car ils vous fournissent un outil avec lequel vous pouvez valider que votre implémentation répond aux exigences.

Tous les tests, qu'il s'agisse de tests unitaires, de tests d'acceptation, de tests d'intégration, etc., sont aussi efficaces que ceux qui les utilisent. Si vous vous approchez de votre travail de manière bâclée, vos tests seront lâches et votre mise en œuvre rencontrera des problèmes. Alors pourquoi s'embêter? Vous vous donnez la peine d'essayer parce que vous devez vous prouver, à vous et à vos clients, que votre logiciel fonctionne et que vous ne rencontrez aucun problème pouvant empêcher son utilisation. Certes, les tests sont un travail supplémentaire, mais la façon dont vous allez les tester déterminera les efforts que vous devrez déployer pour résoudre les bogues après leur publication et les efforts que votre code nécessitera pour être modifiés et conservés.

Je comprends comment fonctionnent les tests unitaires et comment les écrire, mais est-ce que quelqu'un peut affirmer que c'est vraiment une bonne idée et que cela en vaut la peine?

TDD, et vraiment toute méthode qui vous oblige à écrire des tests avant de coder, adopte l’approche que vous avez mise tôt dans l’effort, comme un acompte sur une dette technique future. Au fur et à mesure que vous avancez dans le projet, tout ce qui est manqué ou mal mis en œuvre entraînera une dette plus technique sous la forme de difficultés croissantes de maintenance, ce qui affectera directement les coûts futurs et les besoins en ressources. Les tests préalables garantissent non seulement que vous avez fait un effort pour traiter la dette technique future, mais également que vous codez vos exigences de manière à ce qu'elles puissent être vérifiées simplement en exécutant votre code. Tester d'abord vous donne également la possibilité de valider votre compréhension du domaine du problème avant de vous engager à résoudre le problème en code, et de valider vos efforts d'implémentation.

Il s’agit vraiment de tenter de maximiser la valeur commerciale de votre code. Un code en grande partie non testé et difficile à maintenir est généralement bon marché et rapide à créer, et très coûteux à maintenir tout au long de la vie du produit après sa publication. Le code qui a été testé de manière approfondie au niveau de l’unité est généralement plus coûteux à créer, mais son coût de maintenance est relativement peu élevé tout au long de la durée de vie du produit après sa publication.

En outre, y a-t-il quelque chose qui rend le TDD particulièrement bon pour SCRUM?

TDD n'est pas particulièrement bon pour une méthodologie particulière. C'est simplement un outil. Une pratique que vous pouvez intégrer à vos processus de développement afin de vous aider à atteindre vos objectifs spécifiques. Donc, pour répondre à votre question, TDD est complémentaire à votre méthode, qu’il s’agisse de SCRUM ou de toute autre approche.

S.Robins
la source
6

Les gens pensent que c'est un effort supplémentaire parce que c'est une activité initiale. Ce que vous perdez à temps, vous le retrouverez plus tard.

Mes raisons pour les tests unitaires incluent également:

Vous donne une cible: Vous ne pouvez pas écrire de test si vous ne savez pas ce que le logiciel doit faire. Cela aide à résoudre les problèmes dans les spécifications plus tôt que plus tard.

Vous donne une impression de progrès.

Vous avertit si un changement de code modifie la sortie d'autres zones de code. Cela facilite la refactorisation.

Fournit une couche supplémentaire de documentation (surtout si vous commentez correctement vos tests).

Encourage toutes sortes de bonnes pratiques. Les tests devant s'exécuter rapidement, ils vous incitent à écrire du code découplé et à prendre en charge les moqueries. Tout cela aide à la refactorisation.

Il y en a d'autres aussi abordés dans d'autres messages de ce fil. Ça vaut le coup.

Ian
la source
2

Les tests unitaires ou le développement dirigé par les tests en valent-ils la peine?

Oui (voir les autres réponses)

Est-ce vraiment une bonne idée et en vaut la peine l'effort et le temps?

  • Oui si vous démarrez quelque chose de nouveau (ajoutez un nouveau module ou une toute nouvelle application)
  • Non, s'il existe déjà beaucoup de code existant qui n'a pas été développé et qui doit être étendu (hérité).

À mon avis, le développement piloté par les tests est plus efficace si vous écrivez les tests unitaires avant le code réel. De cette manière, le code qui remplit les tests est clairement séparé avec un minimum de références externes facilement testable.

Si le code existe déjà sans les tests unitaires, l'écriture ultérieure des tests unitaires demande généralement beaucoup de travail supplémentaire, car le code n'a pas été écrit pour faciliter les tests.

Si vous utilisez TDD, le code est facilement testable.

k3b
la source
2

Permettez-moi d'aborder la question de l'autre côté. Que se passe-t-il lorsque vous développez une application non triviale sans tests unitaires? Si vous avez un bon service d’assurance qualité, l’une des premières choses qui se produira est que vous constaterez que vous avez un grand nombre de problèmes signalés. Pourquoi parce que vous n'avez pas testé ce que vous aviez fait et présumé que cela fonctionnerait et parce que vous n'avez pas prêté tant d'attention aux exigences et que votre candidature ne les satisfait pas. Retour à la planche à dessin pour réécrire et corriger. Maintenant que vous avez résolu le problème et trouvé un nouvel ensemble de problèmes, car vous n'aviez aucun moyen de vérifier que vos correctifs n'affectaient rien d'autre avant de passer au contrôle qualité. Oops, la date limite est maintenant passée et la direction en est bouleversée.

La situation est pire si vous n’avez pas un bon service d’assurance qualité car alors les utilisateurs trouveront les bogues et non seulement cela rendra votre patron mécontent, il pourra mettre l’environnement de production à genoux et même des milliers de personnes seront à l’écart. un arrêt pendant que vous corrigez les bugs que les tests unitaires auraient évités. Ce n'est pas un bon choix de carrière.

Maintenant, supposons que cette approche de cow-boy dure des années? Maintenant, chaque changement, même insignifiant, semble faire apparaître de nouveaux problèmes insoupçonnés. Non seulement cela, mais beaucoup de choses que vous aimeriez faire pour améliorer l'application, vous ne pouvez pas le faire parce qu'elles sont trop risquées ou trop chères, voire les deux. Vous mettez donc des correctifs sur les correctifs, ce qui rend le système de plus en plus compliqué, plus buggier et plus difficile à utiliser.

Les utilisateurs commencent à s'interroger sur vos estimations de temps car ils ne cessent de grossir et qu'il est difficile de leur expliquer que le système est devenu un tel gâchis, il est difficile de savoir où faire les changements et encore plus difficile de s'assurer qu'ils ne le sont pas. t casser quelque chose d’autre.

J'ai travaillé dans un endroit comme celui-ci où, après dix ans de développement, nous ne pouvions pratiquement rien faire pour résoudre les véritables problèmes, car nous ne pouvions pas savoir laquelle des centaines d'applications client personnalisées risquait de ne pas fonctionner. Les développeurs initiaux étaient très bien les "tests unitaires, nous n’avons pas besoin de tests unitaires puants" du genre développeurs. Tous ceux qui les ont suivis ont souffert de leur myopie.

Sans tests unitaires, les logiciels sont plus problématiques et prennent plus de temps à développer et à maintenir. Pourquoi ne voudriez-vous pas faire des tests unitaires? Le temps que vous passez à écrire le test sera bien inférieur à celui que vous auriez dû résoudre plus tôt (plus tôt le bogue sera détecté, moins de temps à réparer) et à des problèmes que vous auriez évités en écrivant les tests. d’abord qui donne une meilleure compréhension des exigences avant de commencer à coder.

HLGEM
la source
1

Tout le code que vous écrivez doit être testé à un moment donné. Vous ne voulez pas tout écrire en une fois, puis appuyez sur le bouton Compiler et croisez les doigts. Vous écrivez et compilez de petits blocs et envoyez des entrées soigneusement élaborées dans votre code pour vérifier qu’il fait ce que vous pensez. Ensuite, vous supprimez généralement votre appareil de test ad-hoc et passez au composant suivant.

Avec les tests unitaires, cela simplifie ce processus et vous donne une excuse pour garder vos tests. Ainsi, si vous apportez des modifications qui cassent les éléments que vous avez testés dans le passé, vous pouvez capturer cette régression de manière explicite au lieu de la laisser affecter d'autres parties de votre code. Cela a une réelle valeur.

En ce qui concerne l'approche TDD du refactorateur rouge-vert, je trouve cela un peu fastidieux. Mais a chacun le sien.

tylerl
la source
1
Pour mon 2c: Afin de savoir si vos tests fonctionnent réellement, vous devez les voir échouer avant de les voir réussir. J'ai malheureusement vu de nombreux développeurs écrire des tests qui semblaient fonctionner, mais lorsque les conditions de test ont été modifiées, le code réussit quand même le test, même s'il aurait dû échouer. Si le test échoue en premier et passe en second, il est plus probable que vous ayez écrit un test sans erreur. Si vous modifiez le test une fois le code modifié, vous ne pouvez pas être certain que le code est correct. Oui, c'est fastidieux, mais cela a plus de chance d'être correct. :-)
S.Robins
0

La plupart du temps, je trouve que les développeurs résistent à l’idée d’écrire des tests. Ce n'est pas tant qu'ils prétendent que les tests n'ont aucune valeur, mais plutôt qu'ils ne sont qu'un moyen de comprendre comment résoudre un problème particulier. Habituellement, ce problème change en fonction du contexte. Une fois que cela est fait, les tests ne servent à rien et peuvent tout aussi bien être supprimés. Voici un exemple de contextes donnés par mes collègues dans le passé sur la manière de décider quand écrire un test et vous trouverez que la seule réponse possible en fonction de ceux-ci est:

  • le problème en question doit être un exemple de livre de texte pour TDD tel qu'une pile ou une calculatrice
  • le code trivial ne doit pas être testé (invalide l'argument précédent)
  • le code critique ou difficile doit être minutieusement testé (sous-entendu par l'argument précédent)
  • les tests ne doivent pas être étroitement couplés à l'implémentation pour permettre un refactoring complet (invalide l'argument précédent)
  • Il n'est pas nécessaire de tester les effets secondaires, tels qu'appeler un service tiers avec une charge utile spécifique (donc, aucun test de boîte noire).

En fait, j’ai trouvé qu’un type de test est généralement accepté et, à mon avis, inutilisable. À savoir des tests basés sur une interface graphique, tels que l’utilisation de sélénium, webdriver, watir ou arquillian. C'est ainsi que nous obtenons les cycles de construction de 7 heures plutôt que les cycles de construction de 5 minutes sur mes projets TDD.

Ces mêmes développeurs se plaignent généralement avec tout le monde de la gravité du code et de l'incompétence des développeurs précédents. Ils considèrent également qu’il est extrêmement important de concevoir correctement un tableau blanc, un MS Office ou un wiki et de veiller à ce que ce design reste à jour.

Ce dernier est ce qui m'a vraiment fait réaliser que de tels développeurs sont des fraudes. Nous savons tous que tout document de conception qui n'est pas un test unitaire deviendra obsolète et ne sera plus tenu à jour en raison des coûts de maintenance associés. En fait, j'ai essayé de trouver un bon moyen d'exprimer des idées de conception au format MS Office, ce qui était utile et lisible à la fois avant et après l'écriture de code. J'ai échoué dans tous les cas et bien que certaines personnes parviennent à produire un document MS Office qui semble joli, je ne l'ai jamais trouvé utile non plus.

Donc tu as un choix. Vous pouvez faire de la conception et de la documentation en pratiquant TDD, qui est la seule méthode connue et éprouvée pour produire une telle documentation basée sur mes 10 années d’expérience en développement. Ou vous pouvez faire de la politique.

Sebastian Gozin
la source
1
les tests ne sont pas de la documentation. TDD est une bonne pratique, mais trop souvent, les développeurs utilisent les outils de génération automatique qui crachent des souches de test trop simplifiées. Si vous avez un développeur qui résiste à cela, au lieu d’écrire des tests à granularité fine, essayez d’écrire un harnais de test plus grand qui exécute davantage de tout le produit. Ils trouveront cela évidemment utile. Vous devez quand même rédiger une documentation appropriée, il n’ya pas de quoi s’échapper.
gbjbaanb
@gbjbaanb: si les développeurs utilisent des outils d'auto-génération, il existe peut-être des tests unitaires, mais certainement pas de TDD. En TDD, vous êtes censé écrire test avant les méthodes. Vous ne pouvez pas automatiser le scafold du test d'une méthode qui n'existe pas encore. Aussi des tests bien écrits sont la documentation (documentation technique pour les autres développeurs du projet, et non pas les exigences ni manuel utilisateur). Des tests unitaires bien écrits et bien entretenus vous montrent comment les méthodes devraient être des tests. Et si les tests sont régulièrement vérifiés et réussis, ils sont évidemment plus précis que la documentation obsolète. Vous ne pouvez pas nier cela.
Kriss
Unittests peut être une très bonne documentation pour le développeur car il montre des exemples d'utilisation de l'API.
K3B
L’intérêt du sélénium, du WebDriver, etc., est que vous n’avez pas besoin de contrôler manuellement le site Web. Donc, vous ne gagnez pas de temps en les retirant de votre processus de construction, car ils sont eux-mêmes censés vous faire gagner du temps.
Muhd