TDD vs test unitaire [fermé]

117

Mon entreprise est assez nouvelle dans le domaine des tests unitaires de notre code. Je lis sur le TDD et les tests unitaires depuis un certain temps et je suis convaincu de leur valeur. J'ai essayé de convaincre notre équipe que le TDD vaut l'effort d'apprendre et de changer nos mentalités sur la façon dont nous programmons, mais c'est une lutte. Ce qui m'amène à ma (mes) question (s).

Il y en a beaucoup dans la communauté TDD qui sont très religieux sur l'écriture du test puis du code (et je suis avec eux), mais pour une équipe qui se débat avec TDD, un compromis apporte-t-il encore des avantages supplémentaires?

Je peux probablement réussir à amener l'équipe à écrire des tests unitaires une fois que le code est écrit (peut-être comme une exigence pour l'archivage du code) et je suppose qu'il y a encore de la valeur à écrire ces tests unitaires.

Quelle est la meilleure façon d'amener une équipe en difficulté dans TDD? Et à défaut, cela vaut-il toujours la peine d'écrire des tests unitaires même si c'est après l'écriture du code?

ÉDITER

Ce que j'en ai retenu, c'est qu'il est important pour nous de commencer les tests unitaires, quelque part dans le processus de codage. Pour les membres de l'équipe qui appréhendent le concept, commencez par passer davantage au TDD et aux tests. Merci pour la contribution de tout le monde.

SUIVRE

Nous avons récemment lancé un nouveau petit projet et une petite partie de l'équipe a utilisé TDD, le reste a écrit des tests unitaires après le code. Après avoir terminé la partie de codage du projet, ceux qui écrivent des tests unitaires après le code ont été surpris de voir les codeurs TDD déjà terminés et avec un code plus solide. C'était un bon moyen de convaincre les sceptiques. Nous avons encore beaucoup de difficultés de croissance à faire, mais la bataille des volontés semble terminée. Merci à tous ceux qui ont offert des conseils!

Walter
la source
1
Vous pouvez trouver ce fil utile: stackoverflow.com/questions/917334/should-i-use-tdd
Randolpho
29
+1 pour le SUIVI. C'est une belle histoire.
Carl Manaster

Réponses:

76

Si l'équipe ne parvient pas à implémenter TDD, mais qu'elle n'a pas créé de tests unitaires avant ... alors commencez-les en créant des tests unitaires après l'écriture de leur code. Même les tests unitaires écrits après le code sont meilleurs que pas de tests unitaires du tout!

Une fois qu'ils maîtrisent les tests unitaires (et tout ce qui va avec), vous pouvez alors travailler pour les amener à créer les tests en premier ... et à coder ensuite.

Justin Niessner
la source
3
C'est exact, l'équipe ne créait pas de tests unitaires auparavant. Cela ressemble à un bon tremplin vers le TDD complet.
Walter
Je ne peux pas être plus d'accord avec cela. En fait, je pense avoir écrit quelque chose de similaire pour une question similaire il y a quelques mois. Où est-il ... Aah! stackoverflow.com/questions/917334/should-i-use-tdd/…
Randolpho
27

Il vaut toujours la peine d'écrire les tests unitaires après l'écriture du code. C'est juste que parfois c'est souvent plus difficile parce que votre code n'a pas été conçu pour être testable et que vous l'avez peut-être trop compliqué.

Je pense qu'une bonne manière pragmatique d'amener une équipe dans TDD est de fournir la méthode alternative de "test-pendant le développement" dans la période de transition, ou peut-être à long terme. Ils devraient être encouragés à utiliser les sections de code TDD qui leur semblent naturelles. Cependant, dans les sections de code qui semblent difficiles à aborder le test d'abord ou lors de l'utilisation d'objets prédéterminés par un processus A&D non agile, les développeurs peuvent avoir la possibilité d'écrire une petite section du code, puis d'écrire des tests pour couvrir cela. code, et répétez ce processus. Il vaut mieux écrire des tests unitaires pour certains codes immédiatement après avoir écrit ce code que de ne pas écrire du tout de tests unitaires.

Kaleb Brasee
la source
16

Il est à mon humble avis préférable d'avoir une couverture de test de 50% avec "code d'abord, test après" et une bibliothèque terminée à 100%, qu'une couverture de test à 100% et une bibliothèque complétée à 50% avec TDD. Au bout d'un moment, vos collègues développeurs trouveront, espérons-le, amusant et éducatif d'écrire des tests pour tout le publiccode qu'ils écrivent, afin que TDD se faufile dans leur routine de développement.

Asbjørn Ulsberg
la source
3
Je comprends votre dérive mais je me méfie de la "bibliothèque terminée à 100%" avec une couverture de test à 50% ... juste d'après mon expérience, chaque morceau de code qui n'est pas couvert par certains tests contient au moins un bogue. Ou pour le dire autrement: les gens ont tendance à éviter d'écrire des tests pour du code qui bénéficieraient vraiment de quelques tests supplémentaires :)
Aaron Digulla
2
Eh bien, une autre façon de le dire est un code bogué qui a été publié est meilleur qu'un code parfait qui languit pour toujours. De toute évidence , il y a des exceptions toux NASA toux , mais pour la plupart, obtenir votre code là - bas. Vous pouvez toujours ajouter des tests après sa publication.
jcdyer
3
Qu'entendez-vous par «bibliothèque terminée à 100%». Le considérez-vous comme complet si buggy? N'incluez-vous pas testé dans la définition de terminé?
Pascal Thivent
10
être testé n'est pas une condition suffisante pour être exempt de bogues
fa.
2
La couverture de test telle que mesurée par les outils de couverture de test est une arme à double tranchant. Si cela est réalisé en invoquant toutes les méthodes de l'IUT, mais que les tests ne testent pas vraiment un comportement susceptible de se rompre, les développeurs et autres parties prenantes auront un faux sentiment de sécurité. Tout le mouvement vers le TDD au sein de votre organisation peut vous exploser au visage lorsque le comportement critique n'est pas testé, mais vous avez une couverture de test à 100%. Le plus important n'est pas la quantité, mais la qualité.
Doug Knesek
12

Je viens de lire ceci sur un calendrier: "Toute règle, exécutée à son maximum, devient ridicule voire dangereuse." Je suggère donc de ne pas être religieux à ce sujet. Chaque membre de votre équipe doit trouver un équilibre entre ce qu'il pense «juste» en matière de test. De cette façon, chaque membre de votre équipe sera le plus productif (au lieu de, disons, penser "pourquoi dois-je écrire ce test **** ??").

Ainsi, certains tests valent mieux qu'aucun, les tests après le code sont meilleurs que quelques tests et les tests avant le code sont meilleurs qu'après. Mais chaque étape a ses propres mérites et vous ne devriez pas froncer les sourcils, même les petits pas.

Aaron Digulla
la source
"ce qu'ils ressentent" En tant que développeur, je ne me souviens pas avoir jamais eu le moindre désir (correct) de faire des tests unitaires automatisés à travers mes propres sentiments, uniquement manuels. Je ne pense pas que je sois le seul à manquer d'excitation à cause des tests
Gennady Vanin Геннадий Ванин
@ vgv8: Cela signifie que vos tests ne vous aident pas. Il peut y avoir de nombreuses raisons à cela; Je suggère de creuser plus profondément. Tout projet bénéficie de bons tests et souffre de mauvais. Vous remarquerez que lorsque vous commencerez à écrire de bons tests et à partir de ce moment, rien ne pourra vous empêcher d'écrire davantage.
Aaron Digulla
ce qui me semble juste, c'est un niveau de test qui couvre ce que les unités de programmation devraient faire, et à partir d'un niveau fonctionnel: ce que les utilisateurs font normalement, ce qui inclut les mauvais résultats que certains appellent des "bogues rapportés". Si un bug est confirmé, au moins un test est écrit! plus le projet est grand et plus l'équipe est grande, plus c'est important.
DaFi4
12

TDD est une question de design! Donc, si vous l'utilisez, vous serez sûr d'avoir une conception testable de votre code, ce qui facilitera l'écriture de vos tests. Si vous écrivez des tests après l'écriture du code, ils sont toujours précieux, mais à mon humble avis, vous perdrez du temps car vous n'aurez probablement pas de conception testable.

Une suggestion que je peux vous donner pour essayer de convaincre votre équipe d'adopter le TDD consiste à utiliser certaines des techniques décrites dans Fearless Change: Patterns for Introducing New Ideas, par Mary Lynn Manns et Linda Rising .

Diego Dias
la source
3
+1: Le développement piloté par les tests signifie que la conception a été guidée par des considérations de test.
S.Lott
+1. Les tests unitaires ultérieurs vous aideront bien sûr, mais vous perdriez les avantages d'avoir une «conception testable» si vous n'écrivez pas de tests unitaires à l'avance.
Noufal Ibrahim
9

S'ils sont nouveaux dans les tests, IMO commencez par tester le code qui a déjà été écrit et passez lentement à l'écriture des tests en premier. En tant que personne essayant d'apprendre le TDD et novice dans les tests unitaires, j'ai trouvé qu'il était un peu difficile de faire un 180 complet et de changer d'état d'esprit pour écrire des tests avant le code, donc l'approche que je prends est en quelque sorte un mélange 50-50 ; quand je sais exactement à quoi ressemblera le code, j'écrirai le code puis j'écrirai un test pour le vérifier. Pour les situations où je ne suis pas entièrement sûr, je vais commencer par un test et revenir en arrière.

Souvenez-vous également qu'il n'y a rien de mal à écrire des tests pour vérifier le code, au lieu d'écrire du code pour satisfaire les tests. Si votre équipe ne veut pas suivre la voie TDD, ne la forcez pas.

Wayne Molina
la source
6

Je peux probablement réussir à amener l'équipe à écrire des tests unitaires une fois que le code est écrit (peut-être comme une exigence pour l'archivage du code) et je suppose qu'il y a encore de la valeur à écrire ces tests unitaires.

Il n'y a absolument aucun doute sur le fait qu'il y a de la valeur dans le code testé unitaire (quel que soit le moment où les tests ont été écrits) et j'inclus "le code est testé unitaire" dans la "Définition de Terminé". Les gens peuvent utiliser le TDD ou non, à condition qu'ils testent.

En ce qui concerne le contrôle de version, j'aime utiliser des " branches de développement " avec une politique testée unitaire (c'est-à-dire que le code se compile et se construit, tous les tests unitaires réussissent). Lorsque les fonctionnalités sont terminées, elles sont publiées depuis les branches de développement vers le tronc. En d'autres termes, la branche du tronc est la " branche terminée " (pas de courrier indésirable sur le tronc!) Et a une politique d' expédition (peut être libérée à tout moment) qui est plus stricte et comprend plus de choses que "testé à l'unité".

Pascal Thivent
la source
4

C'est quelque chose avec lequel votre équipe devra avoir ses propres succès avant de commencer à y croire. Je vais parler de mon épiphanie nUnit pour tous ceux qui se soucient:

Il y a environ 5 ans, j'ai découvert nUnit en travaillant sur un projet. Nous avions presque terminé la V1.0 et j'ai créé quelques tests juste pour essayer ce nouvel outil. Nous avons eu beaucoup de bugs (évidemment!) Parce que nous étions une nouvelle équipe, avec un délai serré, des attentes élevées (cela vous semble familier?) Etc. Nous avons réorganisé un peu l'équipe et j'ai obtenu 2 développeurs qui m'ont été assignés. J'ai fait une démo d'une heure pour eux et leur ai dit que tout ce que nous écrivions devait être accompagné d'un cas de test. Nous avons constamment couru «derrière» le reste de l'équipe pendant le cycle de développement 1.1 parce que nous écrivions plus de code, les tests unitaires. Nous avons fini par travailler plus, mais voici le gain: lorsque nous avons finalement commencé les tests, nous avions exactement 0 bogue dans notre code. Nous avons aidé tout le monde à déboguer et à réparer leurs bogues. Dans l'après-mort, lorsque le nombre de bogues est apparu,

Je ne suis pas assez stupide pour penser que vous pouvez tester votre chemin vers le succès, mais je suis un vrai partisan des tests unitaires. Le projet a adopté nUnit et s'est rapidement étendu à l'entreprise pour tous les projets .Net à la suite d'un succès. La durée totale de notre version V1.1 était de 9 semaines de développement, donc ce n'était certainement PAS un succès du jour au lendemain. Mais à long terme, cela s'est avéré un succès pour notre projet et l'entreprise pour laquelle nous avons construit des solutions.

Aucun remboursement Aucun retour
la source
"Le projet a adopté nUnit et il s'est rapidement étendu à l'entreprise pour tous les projets .Net" Et que faire si un produit / projet a du code C #, Java, C ++, SQL Server?
Gennady Vanin Геннадий Ванин
Je ne sais pas ... Trouver un moyen de tester tous les composants avant de les déployer en production? Les tests unitaires ne sont qu'une facette d'un plan de test complet avant sa mise en service. Vous pouvez percer des trous dans n'importe quel scénario.
Aucun remboursement Aucun retour
4

Il ne fait aucun doute que les tests (d'abord, pendant ou même après) vous permettront d'économiser votre bacon et d'améliorer votre productivité et votre confiance. Je recommande de l'adopter!

J'étais dans une situation similaire, parce que j'étais un développeur "noob", j'étais souvent frustré quand je travaillais sur un projet d'équipe par le fait qu'une contribution avait cassé la construction. Je ne savais pas si j'étais à blâmer ou même dans certains cas, qui blâmer. Mais j'étais plus inquiet de faire la même chose à mes collègues développeurs. Cette prise de conscience a ensuite motivé l'adoption de certaines stratégies de TDD. Notre équipe a commencé à avoir des jeux et des règles idiots, comme vous ne pouvez pas rentrer chez vous tant que tous vos tests n'ont pas réussi, ou si vous soumettez quelque chose sans test, alors vous devez acheter à tout le monde "bière / déjeuner / etc" et cela a rendu TDD plus amusant.

Dai Bok
la source
3

L'un des aspects les plus utiles des tests unitaires est de garantir l'exactitude continue du code déjà opérationnel. Lorsque vous pouvez refactoriser à volonté, laissez un IDE vous rappeler les erreurs de compilation, puis cliquez sur un bouton pour laisser vos tests détecter d'éventuelles erreurs d'exécution - arrivant parfois dans des blocs de code auparavant triviaux, alors je pense que vous trouverez votre équipe commence à apprécier TDD. Donc, commencer par tester le code existant est certainement utile.

Aussi, pour être franc, j'ai appris plus sur la façon d'écrire du code testable en essayant de tester du code écrit qu'en commençant par TDD. Cela peut être trop abstrait au début si vous essayez de penser à des contrats qui permettront à la fois d'atteindre l'objectif final et de permettre des tests. Mais quand vous regardez le code et que vous pouvez dire "Ce singleton ici gâche complètement l'injection de dépendances et rend les tests impossibles", vous commencez à développer une appréciation des modèles qui facilitent votre vie de test.

David Berger
la source
3

Eh bien, si vous n'écrivez pas d'abord les tests, ce n'est pas "Test Driven", c'est juste des tests. Il a des avantages en soi et si vous avez déjà une base de code, l'ajout de tests est certainement utile même s'il ne s'agit pas de TDD mais simplement de tests.

Ecrire des tests consiste d'abord à se concentrer sur ce que le code doit faire avant de l'écrire. Oui, vous obtenez également un test pour faire cela et c'est bien, mais certains peuvent dire que ce n'est même pas le point le plus important.

Ce que je ferais, c'est former l'équipe sur des projets de jouets comme ceux-ci (voir Coding Dojo, Katas) en utilisant TDD (si vous pouvez faire participer des programmeurs TDD expérimentés à un tel atelier, ce serait encore mieux). Quand ils verront les avantages, ils utiliseront TDD pour le vrai projet. Mais en attendant, ne les forcez pas, ils ne voient pas l'avantage de ne pas le faire correctement.

Kriss
la source
3

Si vous avez des sessions de conception avant d'écrire du code ou si vous devez produire un document de conception, vous pouvez ajouter des tests unitaires comme résultat tangible d'une session.

Cela pourrait alors servir de spécification sur la façon dont votre code devrait fonctionner. Encouragez le jumelage lors de la session de conception, pour amener les gens à parler de la façon dont quelque chose devrait fonctionner et de ce qu'il devrait faire dans des scénarios donnés. Quels sont les cas limites, avec des cas de test explicites pour que tout le monde sache ce qu'il va faire si on lui donne un argument nul par exemple.

Un aparté mais BDD peut aussi être intéressant

danswain
la source
Je n'étais pas au courant de BDD. Je vais devoir en lire plus.
Walter
3

Vous pouvez trouver une certaine traction en montrant un ou deux exemples où TDD entraîne moins d'écriture de code - parce que vous n'écrivez que le code requis pour réussir le test, il est plus facile de résister à la tentation de plaquer l'or ou de s'engager dans YAGNI. Le code que vous n'écrivez pas n'a pas besoin d'être maintenu, remanié, etc., c'est donc une «vraie économie» qui peut aider à vendre le concept de TDD.

Si vous pouvez clairement démontrer la valeur en termes de temps, de coût, de code et de bogues enregistrés, vous constaterez peut-être que c'est une vente plus facile.

Michael Nash
la source
2

Commencer à créer des classes de test JUnit est la façon de commencer, pour le code existant, c'est la seule façon de commencer. D'après mon expérience, il est très utile de créer des classes de test pour le code existant. Si la direction pense que cela va investir trop de temps, vous pouvez proposer de n'écrire des classes de test que lorsque la classe correspondante contient un bogue ou a besoin d'être nettoyée.

Pour le processus de maintenance, l'approche pour amener l'équipe sur toute la ligne serait d'écrire des tests JUnit pour reproduire les bogues avant de les corriger, c'est-à-dire

  • un bug est signalé
  • créer une classe de test JUnit si nécessaire
  • ajouter un test qui reproduit le bogue
  • corrige ton code
  • exécuter le test pour montrer que le code actuel ne reproduit pas le bogue

Vous pouvez expliquer qu'en "documentant" les bogues de cette manière, vous éviterez que ces bogues ne réapparaissent plus tard. C'est un avantage que l'équipe peut ressentir immédiatement.

rsp
la source
2

J'ai fait cela dans de nombreuses organisations et j'ai trouvé que le meilleur moyen de démarrer et de suivre TDD est de mettre en place une programmation en binôme. Si vous avez quelqu'un d'autre sur qui vous pouvez compter et qui connaît TDD, alors vous pouvez vous séparer tous les deux et vous associer à d'autres développeurs pour faire de la programmation par paires en utilisant TDD. Sinon, je formerais quelqu'un qui vous aidera à le faire avant de le présenter au reste de l'équipe.

L'un des principaux obstacles avec les tests unitaires et en particulier le TDD est que les développeurs ne savent pas comment le faire, ils ne peuvent donc pas voir en quoi cela peut valoir la peine. De plus, lorsque vous commencez, c'est beaucoup plus lent et ne semble pas offrir d'avantages. Il ne vous procure vraiment des avantages que lorsque vous êtes bon dans ce domaine. En mettant en place des sessions de programmation jumelées, vous pouvez rapidement amener les développeurs à l'apprendre rapidement et à le maîtriser plus rapidement. De plus, ils pourront en voir des avantages immédiats lorsque vous y travaillerez ensemble.

Cette approche a fonctionné à plusieurs reprises pour moi dans le passé.

John Sonmez
la source
2

Un moyen efficace de découvrir les avantages du TDD est de réécrire de manière significative certaines fonctionnalités existantes, peut-être pour des raisons de performances. En créant une suite de tests qui font un bon travail couvrant toutes les fonctionnalités du code existant, cela vous donne ensuite la confiance nécessaire pour refactoriser à votre guise en toute confiance que vos modifications sont sûres.

Notez que dans ce cas, je parle de tester la conception ou le contrat - les tests unitaires qui testent les détails de l'implémentation ne conviendront pas ici. Mais là encore, TDD ne peut pas tester l'implémentation par définition, car ils sont censés être écrits avant l'implémentation.

Chris Welsh
la source
1

TDD est un outil que les développeurs peuvent utiliser pour produire un meilleur code. J'ai le sentiment que l'exercice d'écriture de code testable est au moins aussi précieux que les tests eux-mêmes. Isoler l'IUT (Implementation Under Test) à des fins de test a pour effet secondaire de découpler votre code.

Le TDD n'est pas pour tout le monde, et il n'y a pas de magie qui incitera une équipe à choisir de le faire. Le risque est que les rédacteurs de tests unitaires qui ne savent pas ce qui vaut la peine de tester écriront beaucoup de tests de faible valeur, qui seront de la chair à canon pour les sceptiques TDD de votre organisation.

Je fais généralement des tests d'acceptation automatisés non négociables, mais je permets aux développeurs d'adopter le TDD comme il leur convient. J'ai mes TDDers expérimentés pour former / encadrer le reste et «prouver» l'utilité par l'exemple sur une période de plusieurs mois.

Il s'agit autant d'un changement social / culturel que technique.

Doug Knesek
la source