Si TDD concerne le design, pourquoi en ai-je besoin? [fermé]

10

Les gourous du TDD nous disent de plus en plus que le TDD n'est pas une question de tests, c'est une question de conception . Je connais donc des développeurs qui créent un très bon design sans TDD. Devraient-ils alors pratiquer le TDD?

SiberianGuy
la source
14
S'ils s'en sortent bien, ils n'en ont pas besoin. Toutes les «meilleures pratiques» ne fonctionnent pas pour tout le monde.
Rook
1
Ma réponse à une question similaire: programmers.stackexchange.com/questions/98485/…
Rei Miyasaka

Réponses:

18

TDD ne m'aide pas seulement à trouver le meilleur design final, il m'aide à y arriver en moins de tentatives.

J'avais l'habitude d'avoir deux ou trois coups de couteau à un problème avant de décider quel design je pensais être le meilleur. Maintenant, ce même temps exact est consacré à la rédaction de tests et à la concentration sur la conception correcte. Et, en prime, cela me laisse avec une suite de tests répétables. Gagner!

Cela dit, il y aura inévitablement des gens pour qui TDD n'offre rien. Tant qu'ils ont encore des tests automatisés et reproductibles à la fin, c'est bien.

pdr
la source
4
en moins de tentatives, vraiment?
SiberianGuy
3
Oui vraiment. TDD m'oblige à penser à une classe en termes de code appelant, ainsi que de sa fonctionnalité, car vous commencez par écrire le code que vous vous attendez à pouvoir écrire pour consommer la classe. Quand j'écris une classe "à l'aveugle", j'ai tendance à me concentrer sur ce qu'elle fait plus que ce que la classe appelante attend, ce qui est presque toujours une erreur.
pdr
4
Voyez - vous, il y a encore ce mot, forced. Je ne sais pas pourquoi les gens ne sont pas plus souvent dérangés par la fréquence du mot «forcé» comme cela se produit dans les discussions sur le TDD. Il ne faut pas être obligé de concevoir quelque chose correctement; ils doivent apprendre comment concevoir les choses correctement, et puis continuer à le faire sans être contraints à, surtout quand cet acte de force est si incroyablement temps.
Rei Miyasaka
3
@Rei: Les gens ne sont pas plus souvent dérangés parce qu'ils savent que l'autre personne veut vraiment dire "poussé" ou "guidé" ou ... et voici une révélation quand vous parlez de développement piloté par les tests ... peut-être "conduit" . Et oui, certains pourraient trouver qu'ils pensent de cette façon naturellement, sans être conduits, je l'ai dit dans le post. Mais vous devez toujours tester votre logiciel afin que vous ne soyez pas beaucoup mieux.
pdr
3
Quand quelqu'un dit "force la conception modulaire", il est en effet forcé. Il est très difficile (voire impossible) de créer un design non composable avec TDD, et c'est une bonne chose. Le problème n'est pas ce résultat final d'être énergique; c'est la quantité d'effort subalterne par cœur qu'il faut. Une bonne conception est une compétence enseignable et apprenable, et du temps devrait être consacré à l'apprentissage. De plus, les tests écrits pour TDD ne ressemblent pas beaucoup aux tests écrits pour détecter les bogues. S'ils le font, quelque chose ne va pas .
Rei Miyasaka
12

Qu'est - ce que ce particulier gourou TDD est vraiment en train de dire est pas que TDD est un processus de conception (bien qu'un certain nombre de personnes ont malheureusement interprété de cette façon). Le message ici est que l'utilisation d'un processus tel que TDD, si vous le faites correctement , aura tendance à améliorer votre conception globale.

Le concept fondamental est bien plus ancien que TDD; la conception pour la testabilité . Si vous adhérez rigoureusement aux principes SOLID , en particulier au principe de responsabilité unique , vous trouverez le code très facile à tester. D'un autre côté, si vous avez tendance à être un peu plus bâclé dans votre conception, vous trouverez probablement le processus d'écriture de tests unitaires pour vous forcer à le faire plus souvent, pour éviter la frustration de (a) trouver ce qui doit être testé, et (b) passer plus de temps à configurer les dépendances qu'à rédiger les tests réels.

Vous ne devez suivre TDD pour obtenir les avantages de cela, mais il ne l' aide à passer les tests tôt - de préférence très rapidement après avoir implémenté une classe, sinon avant ou pendant. Si vous attendez trop longtemps, vous courez le risque des tests "sales hybrides" dont l'auteur parle, qui n'ont pas beaucoup de valeur car ils sont cassants et ont tendance à se casser lors d'une refactorisation inoffensive - sans parler de l'agrandissement -la redéfinition de l'échelle est un processus atrocement difficile.

Vous ne pouvez pas savoir si vous concevez vraiment pour la testabilité si vous n'écrivez pas de tests, et les "tests de fonctionnalités" au hasard avec seulement 15% de couverture de code ne comptent pas.

Bien sûr, vous pouvez créer de bons designs sans jamais écrire un seul test - mais êtes-vous sûr que ce sont de superbes designs? Comment le savez-vous, s'ils ne sont pas clairement spécifiés par les tests? Les tests révèlent de nombreux problèmes, et bien qu'un processus d'assurance qualité puisse trouver des bogues visibles, ils ne découvrent pas de mauvaises décisions de conception.

Aaronaught
la source
1
L'intérêt d'un bon design n'est pas seulement testé. Mais oui, TDD est un bon outil pour repérer les conceptions défectueuses.
deadalnix
4

Réponse simpliste venant de quelqu'un qui s'efforce d'apprendre le TDD: vous n'en avez pas besoin , mais le principal avantage qu'elle vous apporte est, tout simplement, la confiance : la confiance que votre application fonctionne. Confiance que les cas d'utilisation sont satisfaits. Confiance que votre logique est solide pour le module "Foobar". Confiance que votre code est correctement structuré pour être maintenable et extensible six mois plus tard lorsque le PDG veut ajouter une nouvelle fonctionnalité folle qu'il a lue. Confiance que, lorsque votre application se développe, les bases ont été jetées pour que l'architecture ne s'effondre pas ou ne nécessite pas des tas de hacks en désordre pour truquer de nouvelles fonctionnalités.

Je me rends compte que ce qui précède semblait un peu évangélique, mais c'est ainsi que je vois les avantages du TDD. Même si vous pouvez créer de bonnes conceptions solides et bien architecturées en utilisant TDD force votre main à bien faire les choses, puis prouve que les choses sont bien faites, et plus important encore fournit une base de référence pour garder les choses bien. Du peu que j'ai essayé de TDD, son utilisation m'a forcé à nettoyer le code et à suivre les concepts d'ingénierie logicielle appropriés, sinon je ferais la "chose la plus rapide possible", ce qui aboutissait souvent à un code de "piratage" désordonné.

Wayne Molina
la source
+1 TDD est une rétroaction. Comme la plupart des mesures de rétroaction disparaissent, elles sont assez objectives et complètement automatisées, elles peuvent donc être partagées par des membres de l'équipe de tous niveaux. Avant TDD, un bon code était quelque chose que vous "ressentiez" ou qui était confirmé quelque temps après que les utilisateurs aient obtenu le logiciel. Plus la boucle est courte, plus vous vous sentez confiant. Malheureusement, TDD est sujette à l'excès de confiance car il "ressent" un bon design, mais il est beaucoup plus facile de s'autocorriger.
Steve Jackson
2

Je ne peux parler que de mon expérience. Pour moi, TDD a apporté plusieurs choses que je n'avais pas auparavant dans ma boîte à outils des habitudes de développement. Cependant, il convient de répéter que TDD n'est pas une solution à tout. J'essaie toujours de séparer l'exploration et la mise en œuvre prête à la production. Le TDD en phase d'exploration n'est absolument pas nécessaire et ralentit même. D'un autre côté, pour le code prêt à la production, il apporte plusieurs avantages qui, à court et à long terme, sont très précieux pour la santé mentale des développeurs et le karma du projet.

  • TDD me fait réfléchir avant d'implémenter, ce qui est généralement une très bonne pratique qui évite beaucoup de shoot et oublie les solutions
  • Cela me fait réfléchir par petites portions de problème, m'obligeant à casser la solution aux petits morceaux qui s'emboîtent.
  • Cela me fait écrire du code très découplé parce que chaque fois que je dois coller / simuler / truquer quelque chose qui ne rentre pas dans le problème, j'en lance naturellement un "WTF, pourquoi devrais-je le faire si je n'ai pas à être couplé avec lui" . Et cela me fait mieux comprendre les liens entre les choses.
  • Il me donne un ensemble de vérifications facilement exécutables pour mon code, donc je n'ai pas à passer par un style de débogage de "var_dump", "p", "pp", "echo" douloureux. Il signale simplement ce qui ne va pas, quand c'est mal. Et si je n'ai pas encore de chèque, il suffit d'ajouter un test simple pour le vérifier encore et encore.
  • Cela me rend certain que mon code fonctionne si tous les tests réussissent avant le déploiement. Ensuite, au lieu de manger mes ongles, je vais manger un gâteau et boire du café et profiter de mes après-midi.
  • Les tests de haut niveau sont très agréables dans les cas où vous devez refactoriser quelque chose. Si mon module doit fournir des fonctionnalités au monde extérieur et que j'ai développé des tests fonctionnels / d'intégration / de concombre pour prouver qu'il fonctionne correctement, je serai très courageux pour refactoriser l'enfer de ce code. Plusieurs fois, j'ai été confronté au code qui n'avait pas de tests et je devais le refactoriser. Dans ce cas, il y avait deux façons de procéder. 1) laisser tomber le code 2) ignorer les modifications et le laisser tel quel.

Il y a une chose que TDD ne résout pas. Si vous ne savez pas comment construire la chose que vous construisez, alors TDD ne produira pas de solution pour vous. Vous devez avoir une "conception" approximative ou une vue d'ensemble du problème et de la solution. TDD vous fera simplement l'implémenter de manière plus élégante et maintenable avec le code de meilleure qualité.

Enfin, je préfère penser en termes BDD qui s'appuient sur les pratiques TDD. BDD me fait implémenter une solution en utilisant le vocabulaire du domaine et rendre le logiciel mieux adapté au problème.

ivanjovanovic
la source
1

Il peut y avoir de nombreuses façons de réaliser un grand design, et il existe incontestablement de nombreuses interprétations différentes de ce qui constitue un "grand" - ou même un "bon". Je soupçonne que la plupart des TDDers ne seraient pas d'accord avec vous sur la définition - que si nous regardions le code que vous jugez génial, nous le considérerions moins que génial. TDD nous conduit à certaines qualités très spécifiques, et ces qualités sont rarement trouvées dans le code non-TDD.

La testabilité, évidemment, est l'une de ces qualités, et la plus importante. Des méthodes et des classes extrêmement petites sont peut-être une sous-caractéristique, ce qui conduit à une excellente dénomination. Peut-être que vous connaissez des programmeurs qui atteignent ces qualités sans faire de TDD, mais je ne le fais pas.

Carl Manaster
la source
1
Vous trouveriez presque certainement ces mêmes qualités dans le code produit par un processus de cascade, par exemple pour l'armée, l'espace, etc. la plupart des organisations pour les projets de tous les jours.
Aaronaught
@Aaronaught Dites cela à l'équipe de Mars Climate Orbiter . :-)
Eric King
J'avais une certaine expérience du processus de la cascade sur des projets militaires non armés dans les années 90, et également beaucoup de discussions sur les refroidisseurs d'eau avec des vétérans d'autres applications militaires. Le consensus général était que la méthodologie de la cascade et la facturation au prix coûtant majoré produisaient des systèmes de buggy très difficiles à entretenir.
kevin cline