Expérience négative TDD [fermé]

95

Quel est le côté négatif de votre expérience TDD? Trouvez-vous les petits pas (la solution la plus simple pour rendre le test vert) ennuyeux et inutile? Trouvez-vous des tests sans valeur (lorsque le test a un sens initialement, mais que la mise en œuvre finale vérifie la même logique que les autres tests), la maintenance est-elle critique? etc.

Les questions ci-dessus portent sur des choses avec lesquelles je suis mal à l'aise pendant mon expérience TDD. Je suis donc intéressé à savoir si d'autres développeurs ont des sentiments similaires et ce qu'ils en pensent.

Je serais reconnaissant pour les liens vers des articles décrivant les aspects négatifs de TDD (Google est rempli d'articles positifs et souvent fanatiques).

Idsa
la source
10
Je suppose que vous n'entendrez pas beaucoup de réponses honnêtes sur les expériences négatives des gens, car TDD est encore dans un état "d'adoption précoce" et que la plupart des gens qui sont intéressés et suffisamment engagés pour l'essayer ne sont pas assez objectifs pour évaluez-le sur ses mérites relatifs. Il faut généralement plusieurs années à l’industrie pour établir réellement les effets à long terme des nouveaux procédés et techniques, et même dans ce cas, il est difficile d’obtenir des réponses claires en raison du manque de contrôles. Bonne question néanmoins, et bonne chance pour obtenir des réponses utiles!
Aaronaught
20
Avez-vous de la difficulté à trouver la négativité sur Internet?!
Eric Wilson
4
@Job (et peut-être d'autres): n'oubliez pas qu'il a posé des questions sur le TDD, pas sur les tests unitaires. TDD! = Tests unitaires.
n1ckp
2
Je suis tenté de répondre à cette question, mais je ne veux pas vraiment commencer car cela prendrait la moitié de ma journée.
Rei Miyasaka
2
Lorsque je passe suffisamment de temps sur des bugs et que, apparemment, je pourrais passer moins de temps à écrire des tests pour chaque chose que j'écris avant de l'écrire, je n'adopterai pas test-first-all-things-TDD. Au lieu de cela, je vais avoir honte de ma tête et commencer à chercher une nouvelle carrière. Pas à propos de bugs que vous dites? Conception? Oui. C'est ça. C'est ça exactement. Et vous n'avez rien appris sur la conception robuste en vous offrant un filet de sécurité et une licence vous permettant de continuer à travailler stupide. Rangez l'EDI et essayez de lire votre code si vous voulez découvrir le vrai problème.
Erik Reppen

Réponses:

95

Comme tout ce qui se trouve sous la bannière "Agile", le TDD est quelque chose qui sonne bien en théorie, mais en pratique, on ne sait pas trop à quel point c'est bon (et comme la plupart des choses "Agiles", on vous dit que si vous ne le faites pas comme tu le fais mal).

La définition de TDD n’est pas gravée dans le marbre: des types comme Kent Beck exigent qu’un test de non-compilation soit écrit avant une seule ligne de code et que chaque ligne de code soit écrite pour réussir un test qui a échoué. La conception à l'avant est minimale et tout est guidépar les tests. Ça ne marche pas. J'ai vu une grande application d'entreprise développée à l'aide de cette méthodologie et j'espère que c'est le code pire que je vois dans ma carrière (ce ne sera pas très loin; malgré le fait que des développeurs talentueux y travaillaient). D'après ce que j'ai vu, il en résulte un grand nombre de tests mal pensés qui vérifient principalement que des appels de fonction se produisent, que des exceptions sont générées lorsque les variables sont nulles et que le cadre moqueur bénéficie d'un entraînement complet (whoop-de-whoop); votre code de production est fortement couplé à ces tests et le rêve d’une refactorisation constante et facile n’apparaît pas - en fait, les gens sont encore moins susceptibles de réparer un code incorrect en raison de tous les tests qu’il va entraîner.

À l'inverse, j'ai entendu des gens dire que TDD signifie concevoir les tests à un niveau élevé dans le cadre de la phase de planification, parallèlement à la conception architecturale. Ces tests peuvent changer au cours du développement à mesure que de nouvelles informations deviennent disponibles, mais ils ont été soigneusement examinés et constituent un bon guide quant à ce que le code devrait réellement faire. Pour moi, cela a du sens.

utilisateur23157
la source
7
+1 "concevoir les tests en amont à un niveau élevé dans le cadre de la phase de planification - parallèlement à la conception architecturale" Cela me semble beaucoup plus raisonnable.
Steven Jeuris
11
@Aaronaught Agile ne signifie pas non plus de planification, mais signifie de planification juste à temps .
Adam Jaskiewicz
25
@Adam Jaskiewicz: J'aime ce qui est "pas de planification préalable". Allez, la planification est par définition initiale . Si vous ne planifiez pas à l'avance, mais pendant l'événement, vous ne planifiez pas du tout. vous improvisez. ;-)
CesarGon
34
@Adam - "Est-ce que les gens sautent vraiment directement dans le codage le premier jour d'une itération?" euh oui C'est l'homme "agile". Le dernier endroit où j'ai travaillé (et je me suis fait virer pour ne pas être "agile"), ils ont réalisé un cycle de publication complet de 3 mois sans jamais planifier une seule ligne de code ou une seule page de documentation. Et oui le code était horrible et oui le logiciel était lent, maladroit et buggy. Le jour de mon arrivée, le responsable m'a dit avec fierté qu'ils étaient "le magasin le plus agile de Londres". Ils étaient bien sûr.
7
Peut ajouter un autre problème: tant que le test est réussi, ça doit être bon. Peu importe que le test lui-même puisse être imparfait et provoquer ainsi des faux négatifs et / ou des faux positifs. Et bien sûr, nécessitant une "couverture de test à 100%" et tout ce qui en est ainsi est par définition parfait, ce qui entraîne des tests inutiles qui ne testent rien mais qui sont écrits uniquement pour obtenir cette couverture à 100%, code non documenté car votre compteur de couverture compte les commentaires. comme code non couvert, etc. etc.
Je suis venu
67

Cette interview de Rich Hickey ( auteur de Clojure ) contient les éléments suivants. Je me sens à 100% sympathique:

La vie est courte et il n'y a qu'un nombre fini d'heures dans une journée. Nous devons donc choisir comment nous passons notre temps. Si nous passons ce temps à écrire des tests, c'est le temps que nous ne dépensons pas pour autre chose. Chacun de nous doit évaluer la meilleure utilisation de son temps afin de maximiser ses résultats, à la fois en quantité et en qualité. Si les gens pensent que passer cinquante pour cent de leur temps à la rédaction de tests optimise leurs résultats, d'accord pour eux. Je suis sûr que ce n'est pas vrai pour moi - je préférerais passer ce temps à réfléchir à mon problème. Je suis certain que pour moi, cela produit de meilleures solutions, avec moins de défauts, que toute autre utilisation de mon temps. Une mauvaise conception avec une suite de tests complète reste une mauvaise conception.

Une autre déclaration similaire de Donald Knuth dans l' interview du livre de Coders at Work, copiée -collée à partir d' ici :

Seibel: En parlant de travail pratique, en plein travail sur The Art of Computer Programming, vous avez pris une pause de dix ans pour écrire votre système de composition TeX. Je crois comprendre que vous avez écrit la première version de TeX complètement à l’écart de votre ordinateur.

Knuth: Lorsque j'ai écrit TeX en 1977 et en 1978, je n'avais évidemment pas de programmation alphabète, mais une programmation structurée. Je l'ai écrit dans un grand cahier longhand, au crayon. Six mois plus tard, après avoir parcouru tout le projet, j'ai commencé à taper à l'ordinateur. Et le débogage en mars 1978 alors que j'avais commencé à écrire le programme en octobre 1977. Le code pour cela se trouve dans les archives de Stanford - tout est écrit au crayon - et bien sûr je reviendrais et changerais un sous-programme au fur et à mesure que j'apprendrais ce qu'il devrait être. C'était un système de première génération, donc beaucoup d'architectures différentes étaient possibles et ont dû être abandonnées jusqu'à ce que j'aie vécu avec lui pendant un certain temps et que je sache ce qui était là. Et c’était un problème d’œuf et de poule: vous ne pouviez pas composer avant d’avoir des polices, mais vous ne pouviez pas avoir de polices tant que vous ne pouviez pas composer. Mais la programmation structurée m'a donné l'idée d'invariants et de savoir comment créer des boîtes noires que je pouvais comprendre. J'ai donc eu confiance que le code fonctionnerait lorsque je le déboguerais enfin. Je sentais que je gagnerais beaucoup de temps si j'attendais six mois avant de tester quoi que ce soit. J'avais assez confiance que le code était à peu près correct.

Seibel: Et le gain de temps serait dû au fait que vous ne perdriez pas de temps à construire des échafaudages et des tronçons pour tester du code incomplet?

Knuth: C'est vrai.

Joonas Pulakka
la source
24
Je pense que vous devez regarder le type de travail que vous faites. Knuth et Hickey parlent de la conception de nouvelles applications (innovantes). Si vous regardez où TDD est populaire (sur-généralisation générale), alors vous vous rendez compte que la plupart des applications écrites de manière TDD ont déjà une architecture bien connue.
sebastiangeiger
4
Je peux voir ce que Rich Hickey veut dire, mais je voudrais ajouter ceci: Mon expérience est que, lorsque vous écrivez les tests, vous devez vraiment réfléchir à votre conception et à la façon dont vous faites en sorte que votre code soit testable. l'expérience, aboutit à une meilleure conception.
Niklas H
3
Étant donné que le PO demande des expériences négatives avec TDD, aucun de vos exemples ne semble pertinent pour cette question, car aucun ne montre un exemple de TDD en action.
Winston Ewert
5
@Michael Borgwardt: Il est relativement facile d'ajouter des tests à une conception existante de bonne qualité afin d'éliminer les bogues dans la mise en œuvre. Mais se débarrasser d'un mauvais design signifie souvent une réécriture complète. L’objectif principal devrait donc être d’obtenir le bon design ; l'exécution est plus facile à corriger plus tard.
Joonas Pulakka
4
La plupart des applications métier n’ont pas l’avantage d’être écrites et / ou gérées par Donald Knuth. La durée de vie d'une application est généralement BEAUCOUP plus longue que son développement principal. Je souhaite que les gens aient écrit plus de tests à l’avance sur mon projet actuel. Maintenant, la maintenance est comme un champ de mines de régressions infinies.
Matt H
58

Mon expérience négative avec TDD a été la première. TDD me semblait formidable, je faisais de l'assurance qualité depuis des années et j'avais encore les horreurs à l'esprit. Je voulais écraser chaque bogue avant qu'il ne devienne une version. Malheureusement, l'utilisation de TDD ne garantit pas que vous passerez de bons tests. En fait, ma prédisposition initiale était d'écrire des tests simples générant du code simple. Code vraiment simple qui contient peu d'abstractions. Des tests très simples, étroitement liés aux éléments internes de la classe. Et une fois que vous avez mis en place quelques milliers de tests itty bitty, vous n’avez sûrement pas l’impression que vous agissez plus rapidement lorsque vous devez en modifier une centaine pour refactoriser votre code afin d’utiliser le très important concept de domaine X.

La lumière s'est allumée pour moi - TDD n'est pas une compétence de test. C'est une compétence de conception. Cela ne peut que vous amener à un code bon, simple, exploitable, avec de la pratique et une conscience constante des instructions de conception dans lesquelles il vous conduit. Si vous écrivez des tests dans un souci de couverture de code, vous allez créer des tests fragiles. Si vous écrivez des tests pour vous aider à concevoir vos abstractions, c'est simplement une manière plus rigoureuse d'écrire du code descendant. Vous commencez par voir le code du point de vue de l'appelant, ce qui vous encourage à lui simplifier la vie, plutôt que de refléter les éléments internes d'une classe sur son bord extérieur.

Je pense que TDD est utile, mais je ne suis pas dogmatique à ce sujet. Si ces "tests sans valeur" rendent la maintenance difficile, supprimez-les! Je traite les tests de la même manière que le reste du code. Si cela peut être refait et simplifier les choses, alors faites-le!

Je ne l'ai pas vu personnellement, mais j'ai entendu dire que certains endroits font le suivi de la couverture du code et du nombre de tests. Donc, si la collecte de métriques est un effet secondaire du TDD, je pourrais aussi voir cela comme un effet négatif. Je supprimerai avec enthousiasme 1000 lignes de code, et si cela rend obsolètes 20 tests et abandonne ma couverture de code%, eh bien.

Steve Jackson
la source
7
Vous l'avez cloué au paragraphe 2.
Sheldon Warkentin
4
"Je ne l'ai pas vu personnellement, mais j'ai entendu dire que certains endroits respectent la couverture de code et le nombre de tests" J'ai vécu dans un tel environnement et aucun code n'a jamais été jeté, car cela provoquerait l'échec d'un test. Jusqu'à ce que je commence à déboguer les tests, et que beaucoup d'entre eux aient des défauts si graves, ils ont forcé le code à produire des résultats incorrects pour que les tests réussissent. C'est à ce moment-là que j'ai formulé la question: "qui teste les tests", à laquelle je n'ai encore jamais obtenu de réponse satisfaisante de la part de la communauté TDD. Tests unitaires pour tests unitaires, ça vous tente?
Jwenting
@jwenting - Et cette anecdote soutient assez bien l'argument de Rei. J'ai trouvé que l'aspect protection de la TDD contre la régression était excessif, même si c'est une idée solide en théorie. Les tests doivent être considérés comme étant maintenus au même niveau que le code de production pour que cela fonctionne, et il est un peu anormal de traiter le code de non-production de cette façon - je vois le même "code pourriture" avec des simulateurs de matériel, des générateurs de code, etc tout le temps.
Steve Jackson
"Des tests très simples et intimement liés aux internes de la classe" <- voilà votre problème. Tester uniquement sur les interfaces publiques. TDD! = UT
Steven A. Lowe
2
@ StevenA.Lowe - Je sais que maintenant, mais il y a 9 ans, ce n'était pas si clair :) "Le TDD n'est pas une compétence d'essai"
Steve Jackson le
41

Je vais me laisser aller ici et déclarer avec une brutale honnêteté que c'est littéralement une perte de temps rituelle. (Dans la majorité des situations.)

J'ai acheté un livre sur les tests unitaires qui traitait également du TDD. Bien que je sois d'accord avec les avantages de l'UT, après environ cent heures de test du TDD, j'ai abandonné le logiciel pour une multitude de raisons. Je suis un peu en train de poster ici, mais TDD:

  1. N'est-ce pas une meilleure documentation qu'une vraie documentation.
  2. Ne pas attraper les bugs ou les régressions .
  3. Mes conceptions ne sont pas vraiment meilleures qu'elles ne le seront si j'applique des concepts de programmation fonctionnelle et de composabilité .
  4. Est-il préférable de passer du temps à réviser le code ou à peaufiner la documentation et les spécifications?
  5. Donne aux gestionnaires un faux sentiment de sécurité lorsqu'ils voient une liste de centaines d'icônes vertes.
  6. Améliore la productivité dans la mise en œuvre d'algorithmes avec des mappages d'entrée-sortie limités.
  7. Est maladroit en ce que vous savez peut- être ce que vous faites à la suite de TDD, mais vous ne comprenez pas pourquoi cela fonctionne si bien, pourquoi vos conceptions sont conçues comme elles le sont.

Une autre préoccupation est le degré de perfection discuté auquel on doit faire TDD pour le faire avec succès. Certains insistent sur le fait que si le TDD n'est pas appliqué de manière persistante par tous les membres de l'équipe dès le début du projet, vous n'en souffrirez que. D'autres insistent sur le fait que personne ne fait jamais TDD à la livre. Si ces deux éléments sont vrais, il s'ensuit que les praticiens du TDD souffrent, qu'ils s'en rendent compte ou non.

Bien sûr, si on fait valoir qu'en faisant les choses comme à TDD, on arrivera à des conceptions qui fonctionnent facilement avec TDD, eh bien, il existe des moyens beaucoup plus rapides pour y parvenir - à savoir, en étudiant réellement les concepts de composabilité. Il y a beaucoup de ressources, beaucoup de théorie mathématique rigoureuse même (principalement dans la programmation fonctionnelle mais aussi dans d'autres domaines). Pourquoi ne pas passer tout votre temps à apprendre ?

Culturellement, le TDD présente les symptômes d’une pratique rituelle. Il monte sur la culpabilité; cela encourage la procédure par rapport à la compréhension; il contient des tonnes de doctrines et de slogans ("simulez-le jusqu'à ce que vous le fassiez" est vraiment alarmant si vous le regardez de manière objective). La définition du mot "rituel" par Wikipedia est en fait assez pertinente:

En psychologie, le terme rituel est parfois utilisé dans un sens technique pour désigner un comportement répétitif systématiquement utilisé par une personne pour neutraliser ou prévenir l'anxiété; c'est un symptôme de trouble obsessionnel-compulsif.

Rei Miyasaka
la source
Perspective très intéressante re: rituel. Vous avez également le sentiment, dans certains milieux, que l'engagement d'un programmeur envers son métier est jugé uniquement proportionnel à son adhésion au TDD.
yalestar
Je dirais que dans certaines situations, cela peut améliorer un design, mais c'est surtout lorsque le design doit être hautement modulaire avec une interface publique très bien définie et facile à utiliser. L'écriture des tests avant d'implémenter la bibliothèque elle-même dans ces cas peut aider à aplanir les bugs dans l'interface publique et à forcer cette modularité.
Jwenting
8
@jwenting Les gens font du TDD parce qu’ils ne savent pas ce qui rend un design modulaire, ils ne peuvent donc jamais retirer leurs roues d’entraînement de 35 "de leurs vélos de 40". Faire une conception modulaire est toujours une tâche gérable si vous comprenez les concepts, car chaque dilemme de votre conception aura une taille raisonnable car il est, dans sa conception, en train de devenir modulaire. Je ne conteste pas que TDD est efficace pour forcer la modularité, mais je ne suis pas d'accord pour dire qu'il faut être forcé de créer des conceptions modulaires. La conception modulaire est une compétence parfaitement apprise et enseignable.
Rei Miyasaka
@jwenting En ce qui concerne la convivialité des interfaces publiques, il existe deux courants de pensée parmi les praticiens du TDD à ce sujet, qui sont tous deux indésirables: rendre tout public afin qu'il puisse être testé, ou laisser les choses privées si elles ne le devraient pas de toute façon . Le premier impose aux utilisateurs finaux des détails d’implémentation inutiles (qui peuvent potentiellement être mal utilisés ou exploités), tandis que le second impose aux tests unitaires de se rapprocher des tests du système. Bien sûr, vous pouvez utiliser des outils de test unitaire pour accéder aux données privées, mais cela n’a pas beaucoup de sens de le faire avec TDD.
Rei Miyasaka
1
@Kall Dans cette interview, il dit "environ 15 à 35% de temps en plus" - pas seulement 15% comme vous l'avez cité. L’étude ne concerne également que Java / C ++ / C # (probablement C # 2, compte tenu de la date) - tous les langages du même paradigme impératif de POO. Je suis certainement plus de 15% et probablement plus de 35% plus productif dans un langage fonctionnel (et même en C # 3), et je produis beaucoup moins de bugs en écrivant du code composable sans état, le même type de bugs que le test améliore, parce que les deux choses résolvent exactement les mêmes types de problèmes. En d'autres termes, bien sûr, réduction de 60 à 90% des bugs, mais par rapport à quoi ?
Rei Miyasaka Le
18

Pour ajouter, un autre problème avec TDD que j'ai remarqué est:

TDD provoque un déplacement par inadvertance de l’attention de l’ équipe de développement du Code Qualité vers les Cas de Test et la Couverture de Code! Personnellement, je n'aimais pas le TDD car cela me rend moins créatif et rend le développement logiciel un processus mécanique ennuyeux ! Les unités de test unitaires sont utiles lorsqu'elles sont utilisées judicieusement, mais deviennent un fardeau lorsqu'elles sont traitées comme un objectif du développement logiciel.

Je connais un gars qui est un manager et techniquement ennuyeux, une fois obsédé par le TDD. C'était une chose tellement magique pour lui qu'il pensait apporter des solutions magiques à tous les problèmes de son logiciel mal architecturé avec du code le moins maintenable. Pour ne pas dire ce qui est arrivé à ce projet, il a lamentablement échoué entre ses mains, alors que tous ses tests étaient verts. J'imagine que TDD l'a aidé à obtenir des informations statistiques telles que "99/100 de mes cas sont verts", etc.

Kiran Ravindranathan
la source
2
On dirait que l'enfer est PHB! Cela me rappelle les entreprises qui introduisent des systèmes de bonus - ce qui se produit naturellement, c’est que les développeurs, au lieu de se concentrer sur le code de qualité, se concentrent sur le respect des exigences en matière de bonus. Inévitablement, vous obtenez un code plus merdique. (Il y a aussi une analogie ici avec la crise bancaire actuelle :-))
TrojanName
Eh bien, TDD n’est pas une technique de gestion de projet, il n’est donc pas étonnant que votre wannabe-manager ait échoué. Par contre, je ne me sens pas moins créatif, je me sens même plus créatif car le développement de tests me donne automatiquement une autre vision de mon code. Cependant, je conviens que le code de production doit être au centre des préoccupations et que les tests ne doivent pas gâcher une bonne architecture logicielle.
Alex
La couverture de code est une préoccupation du test unitaire, pas du TDD. TDD ne s'intéresse qu'aux fonctionnalités et aux tests via des interfaces publiques.
Steven A. Lowe
14

Mon expérience négative principale consiste à utiliser TDD pour éditer le code d'un autre programmeur n'ayant pas de test, ou des tests d'intégration très basiques. Lorsque je vais ajouter une fonctionnalité ou résoudre un problème avec ledit code; Je préférerais d'abord écrire un test (à la manière de TDD). Malheureusement, le code est étroitement lié et je ne peux rien tester sans beaucoup de refactoring.

La refactorisation est quand même un bon exercice, mais il est nécessaire d’obtenir le code dans un état vérifiable. Et après cette étape, je n’ai plus de freins et contrepoids pour voir si mes changements ont brisé quoi que ce soit; à court d'exécuter l'application et d'examiner chaque cas d'utilisation.

D'autre part, l'ajout de fonctionnalités / la correction de bugs à un projet TDD devient très simple. Par nature, le code écrit avec TDD est généralement assez découplé avec de petits morceaux avec lesquels travailler.

Dans tous les cas, le TDD est une ligne directrice. Suivez-le jusqu'à ce que vous obteniez une efficacité maximale. Couverture de test décente et code découplé, code bien écrit.

Sheldon Warkentin
la source
1
S'il est difficile d'écrire des tests unitaires, la séparation des préoccupations est généralement médiocre. Je ne vois pas cela comme la faute de TDD, si quelque chose rend rapidement ces problèmes évidents.
Tom Kerr
7
Ce n'est pas une expérience négative avec TDD, c'est une expérience négative avec un code de merde.
Rei Miyasaka
13

Je me suis rendu compte que parfois je me fie trop à mes tests pour concevoir le système. Je suis fondamentalement trop faible dans les détails de la mise en œuvre pour pouvoir prendre le recul pour regarder la situation dans son ensemble. Cela aboutit souvent à une conception inutilement complexe. Je sais que je suis censé refacturer le code, mais j'ai parfois l'impression de pouvoir gagner beaucoup de temps en prenant le pas en arrière plus souvent.

Cela étant dit, si vous avez un cadre tel que des rails où vos décisions architecturales sont très limitées, ces problèmes sont pratiquement inexistants.

Un autre problème est que vous faites confiance à vos tests aveuglément. La vérité est - comme tout autre code - vos tests peuvent aussi avoir des bugs. Soyez donc aussi critique vis-à-vis de vos tests que de votre implémentation.

sebastiangeiger
la source
2
Peut-être devriez-vous écrire des tests pour vos tests! : p ...... I Kid, I Kid
Aren
+1 +1 +1 +1 (si j'avais 3 comptes fictifs). La phrase n ° 2 est très perspicace et ne comporte pas le biais de confirmation du TDD qui est beaucoup trop répandu.
tgm1024
11

En tant que grand fan de TDD, je vois parfois ces inconvénients

  • Tentation d'écrire trop de tests au nom d'une couverture de code proche de 100%. A mon avis, il n'est pas nécessaire d'écrire des tests
    • pour les getters / setters de propriété simples
    • pour tous les cas où une exception est levée
    • qui vérifie la même fonctionnalité à travers différentes couches. (Exemple: si vous avez la possibilité de vérifier la validation des entrées pour chaque paramètre, il n'est pas nécessaire de répéter tous ces tests via un test d'intégration, également)
  • Les coûts de maintenance du code de test pour des tests similaires, qui ne varient que légèrement (créés par la duplication de code (aka copier-coller-héritage)). Si vous en avez déjà un, il est facile d'en créer un similaire. Mais si vous ne refactorisez pas le code de test, en éliminant la duplication de code en méthodes d'assistance, vous aurez peut-être besoin de temps pour corriger les tests si les détails d'implémentation de votre code métier changent.

  • Si vous êtes pressé par le temps, vous pourriez être tenté d' éliminer les tests cassés (ou de les commenter) au lieu de les corriger . De cette façon, vous perdez l'investissement dans les tests

k3b
la source
2
+1: "Tentation d'écrire trop de tests pour le recouvrement de codec à 100%.": Je suis tombé dans ce piège une fois. Après avoir passé tant d'heures à écrire tous ces tests unitaires, les trois seuls bugs que j'ai trouvés dans mon code étaient: ne sont pas couverts par les tests unitaires et peuvent facilement être trouvés en déboguant le code étape par étape.
Giorgio
9

En tant que développeur de jeux, je n'ai pas encore rencontré plus d'un scénario où TDD en valait la peine. Et l'instance dans laquelle il s'agissait était un morceau de code qui était de nature purement mathématique et qui nécessitait une approche solide pour tester simultanément un très grand nombre de cas extrêmes - un besoin rare.

Peut-être que quelque chose, un jour, changera d’idée, mais parmi les pratiques de XP, l’idée de refactoriser impitoyablement , et de faire évoluer le code de sa propre forme est bien plus importante et conduit à la plus grande productivité pour moi, cf. une citation d' un article de James Newkirk :

Simplicité - "Quelle est la chose la plus simple qui puisse fonctionner?"
Le message est très clair. Compte tenu des exigences actuelles, concevez et écrivez votre logiciel. N'essayez pas d'anticiper l'avenir, laissez-le se développer. Cela se fera souvent de manière très imprévisible, faisant de l’anticipation un coût souvent trop onéreux à payer. "

Les concepts de courage et de resserrement des boucles de rétroaction qu'il mentionne sont également, à mon sens, la clé de la productivité.

Ingénieur
la source
9
Le problème, c’est que, sans tests unitaires, comment savez-vous que votre refactoring sans merci aboutit à un code qui fait la même chose? D'après mon expérience, j'ai constaté que, selon le problème, cela peut prendre moins de temps pour écrire des tests + du code que pour écrire du code lui-même! La raison en est principalement due au fait que, pour certains problèmes, je peux essayer un re-factoriser et retester automatiquement beaucoup plus rapidement que je ne pourrais le tester manuellement, ce qui peut augmenter la vitesse des itérations de manière significative.
Mark Booth
6
Pour les jeux, très souvent, les résultats peuvent être vus. S'ils peuvent être vus et paraissent assez bons, ils seront acceptés, car un jeu est de toute façon censé être une expérience subjective. D'autre part, en prenant par exemple. Dans Diablo 2, par exemple, le nombre d’erreurs dans les formules de combat a montré à quel point le TDD aurait apporté une valeur considérable et leur aurait permis d’économiser un travail considérable sur les correctifs. Pour les problèmes très bien définis, tels que la résolution d'équations, et lorsque ceux-ci ne peuvent pas être jugés par des sorties visuelles au moment de l'exécution, TDD est indispensable pour assurer la correction. Mais c'est une petite fraction du code dans la plupart des jeux.
Ingénieur
Il convient également de noter qu'en raison de la vitesse d'exécution des simulations, il est préférable de surveiller les variables en temps réel, à l'écran, pendant la simulation, plutôt que de s'asseoir avec des fichiers journaux de plusieurs millions de lignes pour regarder après le fait.
Ingénieur
3
Les tests unitaires facilitent beaucoup la refactorisation , selon mon expérience.
Tom Kerr
1
@Nick Le gros problème de l'industrie du jeu réside dans les délais, qui sont toujours: "nous devions livrer la marchandise il y a six mois". Je pense que le temps joue contre les tests unitaires dans des environnements soumis à des contraintes de temps. Dans certains cas, la décision n'est pas correcte, mais dans la plupart des cas, l'envoi sans test est plus rapide. Ça dépend, ça dépend vraiment ...
Coder
7

Mon expérience négative de TDD, aussi limitée soit-elle, est simplement de savoir par où commencer! Par exemple, je vais essayer de faire quelque chose TDD et soit ont aucune idée où commencer sauf tester des choses insignifiantes (puis - je new un Fooobjet, puis - je passer dans Quuxla Baz, et autres. Les tests qui ne teste rien ), ou si je tente de l’implémenter dans un projet existant, j’aperçois qu’il me faudrait réécrire diverses classes pour pouvoir les utiliser dans TDD. Le résultat final est que j'abandonne rapidement la notion.

Cela n'aide probablement pas si souvent que je suis la seule personne dans toute l'entreprise à savoir ce qu'est le test unitaire (TDD ou autre) et pourquoi c'est une bonne chose.

Wayne Molina
la source
1
C'est là des cadres moqueurs entrent en jeu . Instanciez Fooavec Mock objets plutôt que Quuxet Bazdirectement, vous pouvez appeler la fonction que vous voulez tester et vérifier que les simulacres ont été appelés avec les fonctions que vous attendez. Les objets factices constituent la technologie habilitante qui permet de découpler les unités et de les rendre testables. C'est pourquoi les singletons sont diaboliques, car vous ne pouvez souvent pas simplement vous moquer d' eux. * 8 ')
Mark Booth
7

Fanatiques de TDD.

Pour moi, ils ne sont que l'une des nombreuses lignées religieuses qui frappent à ma porte, essayant de prouver que ma façon de faire les choses est irrémédiablement brisée et que l'unique voie vers le salut est Jésus, Kent Back ou Unit Testing.

OMI, leur plus grand mensonge est que TDD vous mènera au salut d' un meilleur design d'algorithme. Voir le célèbre solveur Soduku écrit en TDD: ici , ici , ici , ici et ici

Et comparez le résolveur de sudoku Peter Norvig fait non pas en utilisant TDD, mais en utilisant une ingénierie à l'ancienne: http://norvig.com/sudoku.html

Cesar Canassa
la source
Regardez, nous pourrions discuter encore et encore à ce sujet. Mais j'ai beaucoup trop de travail à faire depuis que j'ai obtenu mon diplôme en conception de jeux à l'université Fullsail. Sur la base de mes cours et de mon travail très exigeant, je peux affirmer que le TDD a vraiment le dessus sur le développement effréné ligne par ligne (manque de conception) des programmeurs paresseux. Ecoutez, je ne le dirais pas, mais c’est vrai: la plupart des développeurs qui ont suivi le programme de CS d’une université normale n’ont généralement pas obtenu leur diplôme, les rares qui l’ont fait n’ont pas migré vers le développement de logiciels, et beaucoup d’entre eux ont à peine réussi à se débrouiller. , ligne par ligne. Université Fullsail a un
Zombies
cours complet uniquement en développement piloté par les tests et qui met vraiment les développeurs sur la bonne voie (par opposition à l’implémentation d’une liste chaînée en c ++).
Zombies
Les liens sont cassés mec!
lmiguelvargasf
Plusieurs années plus tard, @Zombies se penche sur le "biais de confirmation". Une grande partie de ce que nous enseignons tous à CS au collège tombe précisément dans cette catégorie. Jetez un coup d'œil au licenciement
immédiat
Lol man, je traînais ... J'ai écrit qu'il y a si longtemps que j'avais oublié ce petit bijou.
Zombies le
5

Si vous utilisez TDD à partir de ces articles "fanatiques", vous aurez le sentiment que votre logiciel ne contient aucune erreur.

Dainius
la source
1
Pouvez-vous avoir un autre sentiment que de savoir que, pour un ensemble d'entrées donné, votre logiciel renvoie un ensemble de sorties donné?
tant que vous comprenez que tdd est un processus de développement et non une règle d'or pour résoudre tout type de problème, c'est OK. Mais la plupart des gens qui proposent d’utiliser ce processus ont oublié qu’il s’agissait d’un processus de développement et que, comme tout autre processus, ils ont un côté positif et un côté sombre. Ils disent à tout le monde que si vous utilisez tdd, vous aurez un logiciel sans bogues, car vous utiliserez test pour couvrir toutes les fonctionnalités. Et généralement ce n'est pas correct. Dans le meilleur des cas, il y aura un test pour chaque cas (ou au moins une fonctionnalité), mais les tests sont des programmes (qui ont des bugs) et ce ne sont que des tests de boîte noire.
Dainius
4

TDD présente certains avantages:

  • Vous vous concentrez sur la façon d'appeler votre code et sur ce à quoi s'attendre en premier (au moment de l'écriture du test) au lieu de vous concentrer sur la résolution du problème, puis sur un appel de l'application. La modularité facilite la simulation et l’emballage.
  • Les tests garantissent que votre programme fonctionne de la même manière avant et après une refactorisation. Cela ne signifie pas que votre programme est sans erreur, mais qu'il continue de fonctionner de la même manière.

TDD est un investissement à long terme. L'effort est rentable lorsque vous atteignez le mode de maintenance de votre application. Si l'application n'est pas planifiée pour atteindre ce point, vous ne pourrez jamais récupérer l'investissement.

Je considère le cycle rouge-vert du TDD avec les étapes de bébé comme une liste de contrôle pour un avion. Il est ennuyeux et fastidieux de vérifier chaque élément de l'avion avant le décollage, en particulier s'il est trivialement simple (les marches du TDD), mais il a été constaté qu'il accroît la sécurité. En plus de vérifier que tout fonctionne, il réinitialise essentiellement l'avion . En d'autres termes, un avion est redémarré avant chaque décollage.

utilisateur1249
la source
3
Le point d’avantage 2 peut être atteint avec de simples tests unitaires sans approche TDD. Avantage 1, vous devriez faire de toute façon. (Focus sur l'API) Il est toujours tout à fait possible de créer une API de merde à l'aide de TDD, mais oui, vous êtes assuré que cela fonctionnera (pour les tests écrits).
Steven Jeuris
2
La question ne portait pas sur les avantages du TDD. Il y a déjà beaucoup d'autres questions à ce sujet.
Aaronaught
1
@aaronaught, je m'attaque à ses problèmes.
Les réponses devraient répondre à la question .
Aaronaught
1
@aaronaught, puis écrivez-en quelques-unes.
3

Mon expérience négative à propos du TDD est quelque chose que je ressens avec beaucoup de choses nouvelles et excitées. En fait, j'apprécie TDD car cela garantit la validité de mon code, et plus important encore: je peux reconnaître les tests ayant échoué après avoir ajouté un nouveau code ou n’importe quel type de refactoring.

Ce qui m'agace chez TDD, c'est qu'il y a beaucoup de règles ou de directives à ce sujet. Comme il est encore relativement nouveau, nous avons pour la plupart d’entre nous des débutants au TDD. Donc, ce qui fonctionne bien pour certains d’entre nous pourrait ne pas fonctionner pour d’autres. Ce que je veux dire, c’est qu’il n’existe pas vraiment de manière «fausse ou correcte» d’exécuter le TDD: c’est ce qui fonctionne pour moi - et mon équipe si j’en ai une.

Donc tant que vous écrivez des tests - avant ou après le code de production n'a pas d'importance IMHO - je ne suis pas sûr si piloté par les tests signifie vraiment que vous devez suivre toutes les directives qui sont énoncées en ce moment, car elles ne sont pas encore prouvées. la solution idéale pour le travail quotidien. Si vous trouvez un meilleur moyen d'écrire des tests, vous devez le publier sur un blog, en discuter ici ou écrire un article à ce sujet. Donc, dans dix ans environ, nous aurions peut-être partagé suffisamment d'expérience pour pouvoir déterminer quelle règle de TDD peut être considérée comme bonne ou non dans certaines situations.

Alex
la source
+1 Excellent commentaire. Il ne faut vraiment pas que ce soit la seule vraie voie ou aucune voie du tout.
Unpythonic
3

À plusieurs reprises, j’ai écrit un code que j’ai défait le lendemain, car il était maladroit. J'ai redémarré avec TDD et la solution était meilleure. Donc, je n'ai pas trop vécu l'expérience négative du TDD. Cependant, cela étant dit, j'ai passé du temps à réfléchir à un problème et à proposer une meilleure solution en dehors de l'espace TDD.

utilisateur23356
la source
1
Habituellement, une seconde tentative vous donnera plus d'informations sur le problème que la première tentative, TDD ou non.
wobbily_col
3

J'ai constaté que le TDD fonctionne mal en ce qui concerne les systèmes émergents. Développeur de jeux vidéo, j'ai récemment utilisé TDD pour créer un système qui utilise plusieurs comportements simples afin de créer un mouvement réaliste pour une entité.

Par exemple, il existe des comportements qui vous obligent à vous éloigner de zones dangereuses de types différents et des comportements qui vous obligent à vous diriger vers des zones intéressantes de types différents. La fusion de la sortie de chaque comportement crée un mouvement final.

Les entrailles du système ont été mises en œuvre facilement, et TDD a été utile ici pour spécifier la responsabilité de chaque sous-système.

Cependant, j'ai eu des problèmes pour préciser comment les comportements interagissaient et, plus important encore, comment ils interagissaient au fil du temps. Souvent, il n’y avait pas de bonne réponse, et bien que mes tests initiaux aient été concluants, le contrôle de la qualité pouvait continuer à trouver des cas extrêmes dans lesquels le système ne fonctionnait pas. Pour trouver la bonne solution, je devais parcourir plusieurs comportements différents, et si je mettais à jour les tests chaque fois pour refléter les nouveaux comportements avant de vérifier qu'ils fonctionnaient dans le jeu, j'aurais peut-être fini par les rejeter à maintes reprises. J'ai donc supprimé ces tests.

J'aurais peut-être dû subir des tests plus rigoureux prenant en compte les cas critiques QA découverts, mais lorsque vous avez un système comme celui-ci qui repose sur de nombreux systèmes de jeu et de physique, et que vous traitez des comportements au fil du temps, cela devient un peu un problème. cauchemar pour spécifier exactement ce qui se passe.

J'ai presque certainement commis des erreurs dans mon approche et, comme je l'ai dit pour les entrailles du système, TDD a fonctionné de manière brillante et a même pris en charge quelques refacteurs d'optimisation.

tenpn
la source