Inconvénients du développement piloté par les tests? [fermé]

192

Qu'est-ce que je perds en adoptant une conception pilotée par les tests?

N'énumérer que les négatifs; ne mentionnez pas les avantages écrits sous une forme négative.

IanL
la source
J'ai ajouté une réponse indiquant que BDD peut atténuer certains de ces négatifs. Je vous invite à prendre en compte ce facteur lors de la collecte de vos données négatives, car certaines d'entre elles peuvent être éliminées et ne plus être considérées comme négatives.
Kilhoffer le
25
Pour des éclaircissements, je ne suis ni contre ni pour. J'essaie de prendre une décision éclairée sur la question, mais la plupart des gens qui préconisent le TDD ne comprennent pas ou n'admettront pas les points négatifs.
IanL
1
Le titre mentionne "Test Driven Development", mais le corps de la question mentionne "Test Driven Design". Sur laquelle des deux cette question porte-t-elle? Il existe des différences importantes mais subtiles entre les deux. La conception pilotée par les tests consiste à laisser les tests piloter la conception du logiciel. Le développement piloté par les tests est généralement associé à l'écriture de tests avant le code de production (mais ne laisse pas nécessairement les tests influencer la conception).
Jim Hurne
3
TDD est une cage qui retient la créativité du développeur.
Lewis
13
veuillez arrêter de fermer les questions importantes, djesus
Casper Leon Nielsen

Réponses:

129

Plusieurs inconvénients (et je ne prétends pas qu'il n'y a aucun avantage - en particulier lors de l'écriture des fondations d'un projet - cela gagnerait beaucoup de temps à la fin):

  • Gros investissement en temps.Pour le cas simple, vous perdez environ 20% de la mise en œuvre réelle, mais pour les cas compliqués, vous perdez beaucoup plus.
  • Complexité supplémentaire.Pour les cas complexes, vos cas de test sont plus difficiles à calculer, je suggère dans des cas comme celui-ci d'essayer d'utiliser un code de référence automatique qui s'exécutera en parallèle dans la version de débogage / test, au lieu du test unitaire des cas les plus simples.
  • Impacts de la conception. Parfois, la conception n'est pas claire au début et évolue au fur et à mesure - cela vous obligera à refaire votre test, ce qui entraînera une perte de temps importante. Je suggérerais de reporter les tests unitaires dans ce cas jusqu'à ce que vous ayez une idée de la conception.
  • Peaufinage continu. Pour les structures de données et les algorithmes de boîte noire, les tests unitaires seraient parfaits, mais pour les algorithmes qui ont tendance à être modifiés, modifiés ou affinés, cela peut entraîner un gros investissement de temps que l'on pourrait affirmer non justifié. Alors utilisez-le lorsque vous pensez qu'il correspond réellement au système et ne forcez pas la conception à s'adapter au TDD.
Adi
la source
7
Le point principal (4) est - tout système qui n'est pas bien défini et qui est susceptible de continuer à changer pour correspondre à un comportement visuel évolutif, des spécifications d'IA différentes, des algorithmes comportementaux, etc. sur la modification des résultats de test souhaités.
Adi
12
Certes, mais ne serait-ce pas la même chose sans TDD? Sans cela, vous auriez à faire plus de tests manuels, qui souffriraient du même problème.
sleske
50
Le «gros investissement en temps» ne vous fera-t-il pas gagner du temps plus tard lors du développement de votre solution? Surtout avec un complexe? Je suppose que cela devrait vous faire gagner du temps. Ne pas penser à la phase de maintenance où de petits changements peuvent facilement casser le système. ( ou peut-être que je suis juste naïf à propos des tests unitaires + de régression empêchant de futurs bugs )
Robert Koritnik
6
Sergio / Robert, je suis très favorable à l'idée de tests unitaires pour les systèmes génériques et certainement pour les composants, ce qui représente la base même des systèmes. Cela dit, j'ajouterais qu'il faut faire la différence entre ces cas et la simplification excessive de la vie réelle en essayant de prétendre que chaque système peut être traité de cette façon. Tous les systèmes ne peuvent pas être généralisés et simplifiés pour les tests unitaires et si vous essayez de forcer la nature des tests unitaires sur de tels systèmes, vous pouvez facilement passer beaucoup plus de temps à corriger vos tests unitaires qu'à tester réellement les résultats réels.
Adi
3
@Adi: Je pense que vous vous trompez. À mon avis, chaque système peut être testé de cette façon, c'est seulement une question d'autodiscipline.
BlueLettuce16
189

Si vous voulez faire un "vrai" TDD (lire: tester d'abord avec les étapes de refactorisation rouge, vert), alors vous devez également commencer à utiliser des mocks / stubs, lorsque vous voulez tester des points d'intégration.

Lorsque vous commencez à utiliser des simulations, après un certain temps, vous souhaiterez commencer à utiliser l'injection de dépendance (DI) et un conteneur d'inversion de contrôle (IoC). Pour ce faire, vous devez utiliser des interfaces pour tout (qui ont elles-mêmes de nombreux pièges).

À la fin de la journée, vous devez écrire beaucoup plus de code que si vous le faites simplement "à l'ancienne". Au lieu d'une simple classe client, vous devez également écrire une interface, une classe fictive, une configuration IoC et quelques tests.

Et n'oubliez pas que le code de test doit également être maintenu et entretenu. Les tests doivent être aussi lisibles que tout le reste et il faut du temps pour écrire du bon code.

De nombreux développeurs ne savent pas très bien comment faire tout cela "de la bonne façon". Mais parce que tout le monde leur dit que TDD est le seul véritable moyen de développer des logiciels, ils essaient juste du mieux qu'ils peuvent.

C'est beaucoup plus difficile qu'on pourrait le penser. Souvent, les projets réalisés avec TDD se retrouvent avec beaucoup de code que personne ne comprend vraiment. Les tests unitaires testent souvent la mauvaise chose, la mauvaise façon. Et personne ne convient à quoi devrait ressembler un bon test, pas même les soi-disant gourous.

Tous ces tests font qu'il est beaucoup plus difficile de «changer» (contrairement au refactoring) le comportement de votre système et les changements simples deviennent tout simplement trop difficiles et prennent beaucoup de temps.

Si vous lisez la littérature TDD, il y a toujours de très bons exemples, mais souvent dans les applications réelles, vous devez avoir une interface utilisateur et une base de données. C'est là que TDD devient vraiment difficile, et la plupart des sources n'offrent pas de bonnes réponses. Et s'ils le font, cela implique toujours plus d'abstractions: objets fictifs, programmation vers une interface, modèles MVC / MVP, etc., qui nécessitent encore beaucoup de connaissances, et ... vous devez écrire encore plus de code.

Alors soyez prudent ... si vous n'avez pas une équipe enthousiaste et au moins un développeur expérimenté qui sait écrire de bons tests et qui sait aussi quelques choses sur une bonne architecture, vous devez vraiment y réfléchir à deux fois avant de vous lancer sur la route TDD .

Thomas Jespersen
la source
7
En utilisant des outils comme Pex & Moles, vous pouvez facilement éviter d'écrire des interfaces pour chaque petite fichue chose. Les taupes vous aideront énormément.
Robert Koritnik
24
On dirait une critique des tests unitaires et de la programmation orientée objet, pas TDD.
plmaheu
5
Exactement correct ** test unitaire ** - pas seulement TDD - nécessite des mocks / stubs. Et la programmation contre une interface est souvent une bonne idée, il en va de même pour les modèles. Si vous mélangez l'interface utilisateur et la logique, vous passerez un mauvais moment. Si vous devez tester l'interaction DB, vous pouvez toujours vous moquer de votre DAO pour les tests unitaires et utiliser la vraie chose pour un test d'intégration.
TheMorph
1
Je suis d'accord sur le fait qu'une brume a une connaissance de la conception et des tests avant de sauter dans tdd. Ceci est essentiel dans les projets avec nouvelle embauche car ils sont nouveaux pour les deux.
Hitesh Sahu
voter pour la Sagesse
sabsab
66

Lorsque vous arrivez au point où vous avez un grand nombre de tests, changer le système peut nécessiter une réécriture de tout ou partie de vos tests, selon ceux qui ont été invalidés par les changements. Cela pourrait transformer une modification relativement rapide en une modification très longue.

En outre, vous pourriez commencer à prendre des décisions de conception basées davantage sur TDD que sur des principes de conception réellement bons. Alors que vous aviez peut-être une solution très simple et facile qui est impossible de tester la façon dont TDD l'exige, vous avez maintenant un système beaucoup plus complexe qui est en fait plus sujet aux erreurs.

Eric Z Beard
la source
3
Cela peut certainement être un problème, mais je constate que je vois une différence notable dans la façon dont je suis affecté par cela. Tout se résume à «écrire du code testable», je suppose.
Rob Cooper,
2
Scott, l'exemple que je donne habituellement est un SqlDataSource intégré dans une page ASPX. Vous ne pouvez pas automatiser un test pour cela. C'est simple et fait le travail, avec seulement 1 fichier. Le composant testable est l'objet SqlDataSource de MSFT, et c'est déjà fait pour nous. Pas besoin pour nous d'en faire plus.
Eric Z Beard
8
+1 "vous pourriez commencer à prendre des décisions de conception basées davantage sur TDD que sur des principes de conception réellement bons" - le plus grand écueil de TDD IMHO.
András Szepesházi
2
@ScottSaad le problème OMI est que la conception doit être décrite en premier et ensuite elle doit être validée en écrivant des tests et corrigée si nécessaire. J'ai vu de nombreux cas où les gens mettaient en danger une bonne conception juste pour pouvoir écrire un test. En conséquence - la plupart du système a été couvert par des tests mais la conception était vraiment moche. Je pense que cela se produit parce que TDD est poussé aux masses comme méthode très simple suivante idée fausse : if part of the system is covered by tests and they pass, then everything is fine (including design).
Yuriy Nakonechnyy
3
@Yura: C'est intéressant ce que vous dites que les gens mettaient en danger une bonne conception juste pour pouvoir écrire des tests. À mon avis, s'il y avait un bon design, il ne serait pas nécessaire de le compromettre. J'ai vu une fois un tel projet et la base de code était un cauchemar, mais les gens pensaient la même chose - que le design est génial. Je ne suis d'accord qu'avec la partie selon laquelle TDD est poussé vers les masses en tant que méthodologie très simple, mais c'est exactement le contraire. À mon avis, lorsque le code est bien conçu, lorsque vous effectuez un petit changement, il n'y a aucune chance de freiner tous les tests ou une grande quantité d'entre eux.
BlueLettuce16
54

Je pense que le plus gros problème pour moi est l'énorme perte de temps qu'il faut pour "y accéder". Je suis encore très au début de mon voyage avec TDD (voir mon blog pour les mises à jour de mes aventures de test si vous êtes intéressé) et j'ai littéralement passé des heures à commencer.

Il faut beaucoup de temps pour mettre votre cerveau en "mode test" et écrire du "code testable" est une compétence en soi.

TBH, je suis respectueusement en désaccord avec les commentaires de Jason Cohen sur la publication des méthodes privées, ce n'est pas de cela qu'il s'agit. Je n'ai pas rendu plus de méthodes publiques dans ma nouvelle façon de travailler qu'auparavant . Cependant, cela implique des modifications architecturales et vous permet de "hot plug" des modules de code pour rendre tout le reste plus facile à tester. Vous ne devez pas rendre les éléments internes de votre code plus accessibles pour ce faire. Sinon, nous sommes de retour à la case départ avec tout étant public, où est l'encapsulation dans tout cela?

Donc, (IMO) en bref:

  • La quantité de temps nécessaire pour réfléchir (c.-à-d. En fait les tests de grok'ing ).
  • Les nouvelles connaissances requises pour savoir comment écrire du code testable.
  • Comprendre les modifications architecturales requises pour rendre le code testable.
  • Augmenter vos compétences de "TDD-Coder" tout en essayant d'améliorer toutes les autres compétences requises pour notre glorieux métier de programmation :)
  • Organisation de votre base de code pour inclure le code de test sans visser votre code de production.

PS: Si vous souhaitez des liens vers des points positifs, j'ai posé et répondu à plusieurs questions à ce sujet, consultez mon profil .

Rob Cooper
la source
1
Malheureusement, la première réponse raisonnable que j'ai vue ...
Daniel C. Sobral
5
Réponse assez pratique et simple - +1 pour la partie "Mind setting"
ha9u63ar
50

Depuis quelques années que je pratique le développement piloté par les tests, je dois dire que les plus gros inconvénients sont:

Le vendre à la direction

TDD se fait mieux par paires. D'une part, il est difficile de résister à l'envie d'écrire simplement l'implémentation lorsque vous SAVEZ comment écrire une instruction if / else . Mais une paire vous gardera sur la tâche parce que vous le gardez sur la tâche. Malheureusement, de nombreuses entreprises / dirigeants ne pensent pas que ce soit une bonne utilisation des ressources. Pourquoi payer pour que deux personnes écrivent une fonctionnalité, alors que j'ai deux fonctionnalités à faire en même temps?

Le vendre à d'autres développeurs

Certaines personnes n'ont tout simplement pas la patience d'écrire des tests unitaires. Certains sont très fiers de leur travail. Ou, certains aiment juste voir des méthodes / fonctions alambiquées saigner à la fin de l'écran. TDD n'est pas pour tout le monde, mais je souhaite vraiment que ce soit le cas. Cela rendrait la maintenance des choses tellement plus facile pour les pauvres âmes qui héritent du code.

Maintenir le code de test avec votre code de production

Idéalement, vos tests ne s'arrêteront que lorsque vous prendrez une mauvaise décision de code. Autrement dit, vous pensiez que le système fonctionnait dans un sens, et il s'est avéré que non. En cassant un test, ou un (petit) ensemble de tests, c'est en fait une bonne nouvelle. Vous savez exactement comment votre nouveau code affectera le système. Cependant, si vos tests sont mal écrits, étroitement couplés ou, pire encore, générés ( toux VS Test), le maintien de vos tests peut devenir rapidement une chorale. Et, après que suffisamment de tests commencent à générer plus de travail que la valeur perçue qu'ils créent, les tests seront la première chose à supprimer lorsque les plannings sont compressés (par exemple, il arrive à l'heure du resserrement)

Écriture de tests pour couvrir tout (couverture du code à 100%)

Idéalement, encore une fois, si vous respectez la méthodologie, votre code sera testé à 100% par défaut. En règle générale, je pense que je me retrouve avec une couverture de code supérieure à 90%. Cela se produit généralement lorsque j'ai une architecture de style de modèle et que la base est testée et que j'essaie de couper les coins et de ne pas tester les personnalisations du modèle. De plus, j'ai découvert que lorsque je rencontre une nouvelle barrière que je n'avais pas rencontrée auparavant, j'ai une courbe d'apprentissage pour la tester. Je vais admettre avoir écrit quelques lignes de code à l'ancienne, mais j'aime vraiment avoir 100%. (Je suppose que j'étais plus performant à l'école, euh skool).

Cependant, avec cela, je dirais que les avantages du TDD l'emportent largement sur les négatifs pour l'idée simple que si vous pouvez réaliser un bon ensemble de tests qui couvrent votre application mais ne sont pas si fragiles qu'un changement les brise tous, vous le ferez pouvoir continuer à ajouter de nouvelles fonctionnalités le jour 300 de votre projet comme vous l'avez fait le jour 1. Cela ne se produit pas avec tous ceux qui essaient TDD en pensant que c'est une solution miracle à tout leur code bogue, et donc ils pensent que cela peut 't travail, point.

Personnellement, j'ai trouvé qu'avec TDD, j'écris du code plus simple, je passe moins de temps à débattre si une solution de code particulière fonctionnera ou non, et que je n'ai pas peur de changer une ligne de code qui ne répond pas aux critères énoncés par l'équipe.

Le TDD est une discipline difficile à maîtriser et j'y suis depuis quelques années et j'apprends toujours de nouvelles techniques de test. C'est un investissement de temps énorme à l'avance, mais, à long terme, votre durabilité sera beaucoup plus grande que si vous n'aviez pas de tests unitaires automatisés. Maintenant, si seulement mes patrons pouvaient comprendre cela.

casademora
la source
7
Quel était le reste de la phrase se terminant par "(toux VS Test), puis principal"?
Andrew Grimm
+1 pour le problème de vente. :) Je suis en ce moment dans une nouvelle entreprise et je réfléchis à la manière de créer une culture qui permettrait aux compétences de se diffuser librement.
Esko Luontola
2
Comme vous, je considère que certaines sociétés de consultants profitent de la programmation par paires et du TDD juste pour obtenir plus d'argent de leurs clients. Il est assez décevant de voir comment ces clients paient pour des idées qui semblent raisonnables à première vue, comme deux personnes pensent beaucoup mieux que 2 ou que TDD assure que chaque ligne de code est testée, mais en fin de compte, ce ne sont que des excuses pour faire payer un client plus pour quelque chose qu'une seule personne peut faire.
lmiguelvargasf
24

Sur votre premier projet TDD, il y a deux grosses pertes, le temps et la liberté personnelle

Vous perdez du temps car:

  • La création d'une suite complète, refactorisée et maintenable de tests unitaires et d'acceptation ajoute du temps à la première itération du projet. Cela peut être un gain de temps à long terme, mais cela peut également être du temps que vous n'avez pas à perdre.
  • Vous devez choisir et devenir expert dans un ensemble d'outils de base. Un outil de test unitaire doit être complété par une sorte de cadre de simulation et les deux doivent faire partie de votre système de construction automatisé. Vous souhaitez également sélectionner et générer des mesures appropriées.

Vous perdez votre liberté personnelle parce que:

  • TDD est une façon très disciplinée d'écrire du code qui a tendance à se frotter à ceux qui se trouvent en haut et en bas de l'échelle des compétences. Toujours écrire le code de production d'une certaine manière et soumettre votre travail à un examen continu par les pairs peut effrayer vos pires et meilleurs développeurs et même entraîner une perte de personnel.
  • La plupart des méthodes Agiles qui intègrent TDD nécessitent que vous parliez continuellement au client de ce que vous proposez d'accomplir (dans cette histoire / jour / peu importe) et quels sont les compromis. Encore une fois, ce n'est pas la tasse de thé de tout le monde, à la fois du côté des développeurs et des clients.

J'espère que cela t'aides

Garth Gilmour
la source
1
Je ne sais pas si c'est parce que je suis pire ou meilleur .. mais TDD me frotte dans le mauvais sens. C'est parce qu'il m'oblige trop tôt à passer en mode double maintenance. Chaque fois que je change la conception d'une classe, je dois aussi changer les cas de test. J'attends et accepte cela d'une classe mature, mais pas d'une classe que je viens d'écrire la semaine dernière! Puis-je également dire que DI et TDD ne sont pas bien pris en charge par des langages tels que Java et C #. Quelqu'un a vraiment besoin de créer un nouveau langage pour que le coût de TDD et DI soit littéralement nul . Ensuite, nous n'aurons plus cette conversation.
John Henckel
14

TDD vous oblige à planifier le fonctionnement de vos classes avant d'écrire du code pour réussir ces tests. C'est à la fois un plus et un moins.

J'ai du mal à écrire des tests dans un "vide" - avant qu'un code n'ait été écrit. D'après mon expérience, j'ai tendance à trébucher sur mes tests chaque fois que je pense inévitablement à quelque chose en écrivant mes cours que j'ai oublié en écrivant mes tests initiaux. Il est alors temps non seulement de refactoriser mes cours, mais ÉGALEMENT mes tests. Répétez cette opération trois ou quatre fois et cela peut devenir frustrant.

Je préfère d'abord rédiger un brouillon de mes cours puis écrire (et maintenir) une batterie de tests unitaires. Après avoir un brouillon, TDD fonctionne bien pour moi. Par exemple, si un bogue est signalé, j'écrirai un test pour exploiter ce bogue, puis je corrigerai le code pour que le test réussisse.

Chrass
la source
1
Alors que vous devriez avoir une idée de l'architecture de votre système, vous n'avez pas besoin d'en savoir beaucoup à l'avance lorsque vous effectuez TDD. TDD signifie que les tests CONDUISENT la conception, donc cela changera au fur et à mesure que vous implémenterez plus de scénarios de test
casademora
4
Je suis d'accord avec le vide. Les tutoriels originaux de TDD où vous écrirez le test sans aucun code - et obtiendrez une erreur de compilation - sont fous.
mparaz
Il est faux de supposer que vous pouvez écrire les tests une fois et ne pas les modifier. Ils sont du code et chaque code nécessite une refactorisation éventuelle après avoir effectué des modifications. Les tests ne font pas exception. La refactorisation des tests est indispensable si vous souhaitez les maintenir maintenables.
Roman Konoval le
12

Le prototypage peut être très difficile avec TDD - lorsque vous n'êtes pas sûr de la voie que vous allez prendre pour une solution, l'écriture des tests à l'avance peut être difficile (à part des très larges). Cela peut être pénible.

Honnêtement, je ne pense pas que pour le «développement de base» pour la grande majorité des projets, il y ait un réel inconvénient; il est beaucoup plus bas qu'il ne devrait l'être, généralement par des gens qui croient que leur code est assez bon pour qu'ils n'aient pas besoin de tests (ce n'est jamais le cas) et des gens qui ne peuvent tout simplement pas être dérangés de les écrire.

Calum
la source
9

Eh bien, et cet étirement, vous devez déboguer vos tests. En outre, il y a un certain coût en temps pour écrire les tests, bien que la plupart des gens conviennent que c'est un investissement initial qui porte ses fruits sur la durée de vie de l'application, à la fois en termes de débogage et de stabilité.

Le plus gros problème que j'ai personnellement rencontré, cependant, est de prendre la discipline nécessaire pour passer les tests. Dans une équipe, en particulier une équipe établie, il peut être difficile de les convaincre que le temps passé en vaut la peine.

Tim Sullivan
la source
13
Aha - mais c'est là qu'intervient TDTDD. Test Driven Test Driven Development.
Snowcrash
3
Je trouve encore parfois des bugs dans mes tests. Alors maintenant, je pratique TDTDTDD.
HorseloverFat
@SnowCrash +1 Je regardais autour de Google pour voir combien de temps les gens passent à tester leurs tests, puis j'ai vu cette réponse. J'ai officiellement trouvé cela parce que je me posais des questions sur TDTDTDD.
BalinKingOfMoria réintègre les CM
1
Je crois que l'avenir est (TD) <sup> ∞ </sup> TDD. J'ai jusqu'à présent un fichier: il contient la lettre "x".
mike rodent
Je suis d'accord avec @Tim. Convaincre les membres de l'adopter est la partie la plus difficile.
Olu Smith
7

Si vos tests ne sont pas très approfondis, vous risquez de tomber dans un faux sentiment de «tout fonctionne» simplement parce que vos tests réussissent. Théoriquement, si vos tests réussissent, le code fonctionne; mais si nous pouvions écrire du code parfaitement la première fois, nous n'aurions pas besoin de tests. La morale ici est de vous assurer de faire un test de santé mentale par vous-même avant d'appeler quelque chose de complet, ne vous fiez pas uniquement aux tests.

Sur cette note, si votre vérification de la santé mentale trouve quelque chose qui n'est pas testé, assurez-vous de revenir en arrière et d'écrire un test pour cela.

Aaron Lee
la source
Je ne crois en aucune clause de santé mentale depuis que j'ai grandi.
mike rodent
7

L'inconvénient du TDD est qu'il est généralement étroitement associé à la méthodologie «Agile», qui ne importance à la documentation d'un système, mais la compréhension derrière pourquoi un test `` devrait '' renvoyer une valeur spécifique plutôt que toute autre réside uniquement dans le développeur. tête.

Dès que le développeur quitte ou oublie la raison pour laquelle le test renvoie une valeur spécifique et non une autre, vous êtes foutu. TDD est correct SI il est correctement documenté et entouré d'une documentation lisible par l'homme (c'est-à-dire un gestionnaire aux cheveux pointus) qui peut être consultée dans 5 ans lorsque le monde change et que votre application en a également besoin.

Quand je parle de documentation, ce n'est pas un texte de présentation, c'est une écriture officielle qui existe en dehors de l'application, comme des cas d'utilisation et des informations de base auxquelles peuvent se référer les gestionnaires, les avocats et la pauvre sève qui doit mettre à jour votre code en 2011.

Ron McMahon
la source
1
Parfaitement mis. Je ne pourrais pas être plus d'accord. Pour moi, les tests ne permettent certainement pas de décrire des définitions de problèmes de niveau supérieur dans le monde réel. Une bonne documentation a fait ses preuves à maintes reprises. En tant que technicien. l’âge de l’industrie, les notions éprouvées doivent être abandonnées avec une prudence toujours plus grande. Le code d'auto-documentation est une notion ridicule. Je crois au prototypage, à la refactorisation et à l'agilité de ne jamais définir un problème au départ. Cependant, ironiquement, le fait de ne pas sur-définir le problème au début fait du stubbing pour TDD un champ de mines.
wax_lyrical
1
Je pense que c'est injuste. Les bonnes pratiques TDD condamnent les nombres magiques et les tests obscurs. Les tests doivent être simples et aussi, ou de préférence plus lisibles que votre code de production lui-même. vos tests SONT la documentation. assurez-vous qu'ils y ressemblent. cette réponse ressemble un peu à dire "la documentation est mauvaise parce que parfois les gens écrivent une très mauvaise documentation" ou "les classes sont mauvaises parce que j'ai vu des classes divines difficiles à gérer".
sara
6

J'ai rencontré plusieurs situations où TDD me rend fou. Pour en nommer:

  • Maintenabilité du scénario de test:

    Si vous êtes dans une grande entreprise, il est fort probable que vous n'ayez pas à écrire les cas de test vous-même ou du moins la plupart d'entre eux sont écrits par quelqu'un d'autre lorsque vous entrez dans l'entreprise. Les fonctionnalités d'une application changent de temps en temps et si vous n'avez pas de système en place, tel que HP Quality Center, pour les suivre, vous deviendrez fou en un rien de temps.

    Cela signifie également qu'il faudra beaucoup de temps aux nouveaux membres de l'équipe pour saisir ce qui se passe avec les cas de test. À son tour, cela peut se traduire par plus d'argent nécessaire.

  • Tester la complexité de l'automatisation:

    Si vous automatisez une partie ou la totalité des cas de test dans des scripts de test exécutables par la machine, vous devrez vous assurer que ces scripts de test sont synchronisés avec leurs cas de test manuels correspondants et conformes aux modifications de l'application.

    De plus, vous passerez du temps à déboguer les codes qui vous aident à détecter les bogues. À mon avis, la plupart de ces bogues proviennent de l'échec de l'équipe de test à refléter les changements d'application dans le script de test d'automatisation. Les changements dans la logique métier, l'interface graphique et d'autres éléments internes peuvent empêcher l'exécution de vos scripts ou leur exécution de manière non fiable. Parfois, les changements sont très subtils et difficiles à détecter. Une fois que tous mes scripts ont signalé un échec car ils ont basé leur calcul sur les informations du tableau 1 alors que le tableau 1 était maintenant le tableau 2 (car quelqu'un a échangé le nom des objets de la table dans le code d'application).

Martin08
la source
Cela ne concerne pas du tout le TDD. Si quelqu'un d'autre dans un autre département écrit vos cas de test, vous ne faites pas TDD. Si vous avez des cas de test manuels, vous ne faites pas TDD. Si le code de votre bibliothèque casse et que vos tests échouent en raison de modifications apportées à l'interface graphique, vous ne faites probablement pas non plus TDD. Cela ressemble plus à des arguments contre les grands départements d'assurance qualité inefficaces.
sara
5

Le plus gros problème, ce sont les personnes qui ne savent pas comment écrire les tests unitaires appropriés. Ils écrivent des tests qui dépendent les uns des autres (et ils fonctionnent très bien avec Ant, mais échouent soudainement quand je les lance depuis Eclipse, juste parce qu'ils s'exécutent dans un ordre différent). Ils écrivent des tests qui ne testent rien en particulier - ils déboguent simplement le code, vérifient le résultat et le transforment en test, en l'appelant "test1". Ils élargissent le champ des classes et des méthodes, simplement parce qu'il sera plus facile de leur écrire des tests unitaires. Le code des tests unitaires est terrible, avec tous les problèmes de programmation classiques (couplage lourd, méthodes longues de 500 lignes, valeurs codées en dur, duplication de code) et est un enfer à maintenir. Pour une raison étrange, les gens traitent les tests unitaires comme quelque chose d’inférieur au «vrai» code, et ils t se soucient de leur qualité du tout. :-(

rmaruszewski
la source
4

Vous perdez beaucoup de temps à passer des tests. Bien sûr, cela pourrait être enregistré à la fin du projet en attrapant les bogues plus rapidement.

Joel Coehoorn
la source
Est-ce vraiment une façon négative ou sournoise de dire un positif?
IanL
3

Le plus gros inconvénient est que si vous voulez vraiment faire le TDD correctement, vous devrez beaucoup échouer avant de réussir. Étant donné le nombre de sociétés de logiciels qui fonctionnent (dollar par KLOC), vous finirez par être viré. Même si votre code est plus rapide, plus propre, plus facile à maintenir et contient moins de bogues.

Si vous travaillez dans une entreprise qui vous paie par les KLOC (ou les exigences mises en œuvre - même si elles ne sont pas testées), restez à l'écart du TDD (ou des révisions de code, ou de la programmation par paires, ou de l'intégration continue, etc., etc., etc.).

Vasco Duarte
la source
3

Vous perdez la possibilité de dire que vous avez «terminé» avant de tester tout votre code.

Vous perdez la possibilité d'écrire des centaines ou des milliers de lignes de code avant de l'exécuter.

Vous perdez l'occasion d'apprendre par le débogage.

Vous perdez la flexibilité d'expédier du code dont vous n'êtes pas sûr.

Vous perdez la liberté de coupler étroitement vos modules.

Vous perdez l'option d'ignorer l'écriture de documentation de conception de bas niveau.

Vous perdez la stabilité qui accompagne le code que tout le monde a peur de changer.

Oncle Bob
la source
1
Dépend de votre définition de «livrer une solution à temps» - c'est-à-dire «toute ancienne solution partiellement cassée à temps» ou «livrer des solutions fonctionnelles à temps». Vous perdez certainement la capacité de livrer des solutions partiellement cassées à temps. En ce qui concerne la vitesse de développement, j'aime la métrique "temps écoulé entre le début du développement et une semaine de déploiement en direct sans faille". Si vous le mesurez équitablement, il est même difficile d'arrêter l'horloge sur un travail copmlex non TDD.
Dafydd Rees
47
-1, c'est exactement ce que le PO a dit qu'il ne voulait pas.
erikkallen
1
Beaucoup de vraies déclarations, mais: ce qu'a dit erikkallen. -1.
j_random_hacker
@ j_random_hacker dit hacker ... LOL
Dan
seule la troisième déclaration est légitime "apprendre par le débogage est perdu"
YEH
2

J'appuie la réponse sur le temps de développement initial. Vous perdez également la capacité de travailler confortablement sans la sécurité des tests. J'ai également été décrit comme un nutbar TDD, donc vous pourriez perdre quelques amis;)

Chris Canal
la source
2

C'est perçu comme plus lent. À long terme, ce n'est pas vrai en termes de chagrin, cela vous fera économiser sur la route, mais vous finirez par écrire plus de code, donc vous passez sans doute du temps à «tester et non coder». C'est un argument erroné, mais vous l'avez demandé!

MarcE
la source
2

Se recentrer sur des exigences difficiles et imprévues est le fléau constant du programmeur. Le développement piloté par les tests vous oblige à vous concentrer sur les exigences banales déjà connues et limite votre développement à ce qui a déjà été imaginé.

Pensez-y, vous finirez probablement par concevoir des cas de test spécifiques, donc vous ne serez pas créatif et ne commencerez pas à penser "ce serait cool si l'utilisateur pouvait faire X, Y et Z". Par conséquent, lorsque cet utilisateur commence à être enthousiasmé par les exigences potentielles cool X, Y et Z, votre conception peut être trop rigoureusement concentrée sur des cas de test déjà spécifiés, et il sera difficile à ajuster.

Ceci, bien sûr, est une épée à double tranchant. Si vous passez tout votre temps à concevoir pour chaque X imaginable, imaginable, X, Y et Z qu'un utilisateur puisse souhaiter, vous ne finirez inévitablement jamais rien. Si vous accomplissez quelque chose, il sera impossible pour quiconque (y compris vous-même) d'avoir une idée de ce que vous faites dans votre code / conception.

Doug T.
la source
Pensez-y, vous finirez probablement par concevoir des cas de test spécifiques, donc vous ne serez pas créatif et ne commencerez pas à penser "ce serait cool si l'utilisateur pouvait faire X, Y et Z". - À mon avis, c'est exactement le contraire. Si vous écrivez des tests unitaires, vous vous interrogez sur les différents cas commerciaux et cela signifie que vous êtes créatif et qu'il est possible de prévoir quelque chose d'imprévu. Toute cette créativité n'est cependant pas importante si votre implémentation a des bugs.
BlueLettuce16
1

Il peut être difficile et long d'écrire des tests pour des données "aléatoires" comme les flux XML et les bases de données (pas si difficiles). J'ai récemment travaillé avec des flux de données météorologiques. C'est assez déroutant d'écrire des tests pour cela, du moins car je n'ai pas trop d'expérience avec TDD.

Vargen
la source
C'est un problème commun. J'ai tendance à les moquer avec des objets codés en dur, puis à tester la base de données séparément. Votre couche métier ne devrait alors fonctionner qu'avec des données statiques, votre DAL sera ensuite testé dans un environnement contrôlé (où vous pourrez y écrire les données, etc.)
Rob Cooper
1

Vous perdrez de grandes classes avec de multiples responsabilités. Vous perdrez également probablement de grandes méthodes avec de multiples responsabilités. Vous pouvez perdre une certaine capacité de refactoriser, mais vous perdrez également une partie du besoin de refactoriser.

Jason Cohen a dit quelque chose comme: TDD nécessite une certaine organisation pour votre code. Cela pourrait être incorrect sur le plan architectural; par exemple, comme les méthodes privées ne peuvent pas être appelées en dehors d'une classe, vous devez rendre les méthodes non privées pour les rendre testables.

Je dis que cela indique une abstraction manquée - si le code privé doit vraiment être testé, il devrait probablement être dans une classe distincte.

Dave Mann

Dave Mann
la source
1

Vous devez écrire des applications d'une manière différente: une qui les rend testables. Vous seriez surpris de voir à quel point c'est difficile au début.

Certaines personnes trouvent le concept de penser à ce qu'elles vont écrire avant de l'écrire trop fort. Des concepts tels que la moquerie peuvent également être difficiles pour certains. TDD dans les applications héritées peut être très difficile si elles n'ont pas été conçues pour les tests. Le TDD autour de cadres qui ne sont pas compatibles avec le TDD peut également être difficile.

Le TDD est une compétence pour que les développeurs juniors puissent avoir du mal au début (principalement parce qu'ils n'ont pas appris à travailler de cette façon).

Dans l'ensemble, bien que les inconvénients soient résolus à mesure que les gens deviennent qualifiés et que vous finissez par résumer le code «malodorant» et avoir un système plus stable.

Peter Gillard-Moss
la source
1

Cela prend un certain temps pour y entrer et un certain temps pour commencer à le faire dans un projet mais ... Je regrette toujours de ne pas avoir fait une approche Test Driven quand je trouve des bugs idiots qu'un test automatisé aurait pu trouver très rapidement. De plus, TDD améliore la qualité du code.

aerlijman
la source
1
  • les tests unitaires sont plus de code à écrire, donc un coût initial de développement plus élevé
  • c'est plus de code à maintenir
  • apprentissage supplémentaire requis
Bob Dizzle
la source
1

Bonnes réponses à tous. J'ajouterais quelques façons d'éviter le côté sombre du TDD:

  • J'ai écrit des applications pour faire leur propre auto-test aléatoire. Le problème avec l'écriture de tests spécifiques est que même si vous en écrivez beaucoup, ils ne couvrent que les cas auxquels vous pensez. Les générateurs de tests aléatoires trouvent des problèmes auxquels vous n'avez pas pensé.

  • Le concept de nombreux tests unitaires implique que vous avez des composants qui peuvent entrer dans des états invalides, comme des structures de données complexes. Si vous vous éloignez des structures de données complexes, il y a beaucoup moins à tester.

  • Dans la mesure où votre application le permet, soyez timide de conception qui repose sur le bon ordre des notifications, des événements et des effets secondaires. Ceux-ci peuvent facilement être abandonnés ou brouillés, ils ont donc besoin de beaucoup de tests.

Mike Dunlavey
la source
Les tests aléatoires peuvent échouer par intermittence et rendre leur répétition difficile
David Sykes
@DavidSykes: Chaque fois que vous effectuez un test aléatoire, vous enregistrez les paramètres, de sorte que s'il échoue, vous pouvez le répéter, ou vous pouvez le répéter plus tard, même s'il n'a pas échoué. Le fait est que cela ne dépend pas de vous de penser les cas de test. Si vous êtes comme moi, vous vous dirigez instinctivement vers des cas de test sûrs.
Mike Dunlavey
0

TDD nécessite une certaine organisation pour votre code. Cela peut être inefficace ou difficile à lire. Ou même mal architecturalement; par exemple, puisqueprivate méthodes ne peuvent pas être appelées en dehors d'une classe, vous devez rendre les méthodes non privées pour les rendre testables, ce qui est tout simplement faux.

Lorsque le code change, vous devez également modifier les tests. Avec la refactorisation, cela peut représenter beaucoup de travail supplémentaire.

Jason Cohen
la source
9
Toutes les méthodes privées devraient être testées par les méthodes publiques qui existeraient de toute façon.
Garry Shutler
Ce n'est pas possible avec toutes les classes. Parfois, vous ne voulez pas simuler toutes les dépendances, etc. et vous souhaitez simplement tester une méthode utilitaire.
Jason Cohen,
+1, c'est vrai. Ajoutez à cela l'exigence d'ajouter parfois des getters / setters aux champs privés juste pour pouvoir configurer et lire correctement l'état pour un test unitaire, même si l'état doit être privé pour la classe.
erikkallen
Pensez à écrire vos tests comme s'il s'agissait d'un document d'exigences vivantes. Ensuite, vous verriez la lumière. Lisez également les modèles de test XUnit.
Scott Nimrod
0

Permettez-moi d'ajouter que si vous appliquez les principes BDD à un projet TDD, vous pouvez atténuer quelques-uns des principaux inconvénients énumérés ici (confusion, malentendus, etc.). Si vous n'êtes pas familier avec BDD, vous devriez lire l'introduction de Dan North. Il a proposé le concept en réponse à certains des problèmes posés par l'application du TDD sur le lieu de travail. L'introduction de Dan au BDD peut être trouvée ici .

Je ne fais cette suggestion que parce que BDD résout certains de ces points négatifs et agit comme un trou d'arrêt. Vous devrez en tenir compte lors de la collecte de vos commentaires.

Kilhoffer
la source
Absolument. Vous devez considérer BDD lors de l'évaluation de TDD.
user9991
Il semble que BDD = développement axé sur le comportement
hayalci
0

Vous devez vous assurer que vos tests sont toujours à jour, le moment où vous commencez à ignorer les feux rouges est le moment où les tests deviennent vides de sens.

Vous devez également vous assurer que les tests sont complets, ou au moment où un gros bogue apparaît, le type de gestion étouffant que vous avez finalement convaincu de vous laisser passer du temps à écrire plus de code se plaindra.

qui
la source
0

La personne qui a enseigné le développement agile à mon équipe ne croyait pas à la planification, vous n'avez écrit que pour la moindre exigence.

Sa devise était refactor, refactor, refactor. J'ai compris que le refactorisme signifiait «ne pas planifier à l'avance».

Jack B Nimble
la source
-1

Le temps de développement augmente: chaque méthode doit être testée et si vous avez une grande application avec des dépendances, vous devez préparer et nettoyer vos données pour les tests.

Mouna Cheikhna
la source
Je développe depuis 36 ans maintenant ce post peut vous donner de bons conseils: stackoverflow.com/questions/738539/tdd-how/45971814#45971814
user2288580