Il y a un peu plus d'un an, j'ai eu la chance de pouvoir prendre une pause de 9 mois. J'ai décidé qu'à ce moment-là, je perfectionnerais mes compétences en C #. J'ai commencé à travailler sur un tas de projets et je me suis forcé à suivre TDD.
Ce fut un processus assez instructif.
C'était difficile au début, mais au fil du temps, j'ai appris à écrire plus de code testable (qui, en fin de compte, a tendance à être plus solide) et au cours du processus, j'ai également affiné mes compétences en conception OO.
Maintenant, je suis de retour sur le marché du travail et je remarque quelque chose d'étrange.
Je préfère ne pas suivre TDD.
Je trouve que TDD me ralentit et rend en fait plus difficile la conception d'une application propre.
Au lieu de cela, j'ai adopté une approche légèrement (massivement) différente:
- Choisissez une tranche verticale de travail
- Développer un prototype fonctionnel
- Refactoriser jusqu'à ce que tout soit beau et bien rangé
- Asseyez-vous et appréciez le code magnifiquement SOLIDE et testable que j'ai écrit.
Vous avez peut-être remarqué que l'étape 1 n'était pas «définir la surface publique de ma cible de test» et l'étape 2 n'était pas «tester le bejesus hors de ladite surface publique». Vous avez peut-être également remarqué qu'aucune des étapes ne comporte de test. J'écris du code testable, mais je ne le teste pas ... pour l'instant.
Maintenant, je tiens à préciser que je ne renonce en fait à aucun type de test. Le code que j'écris fonctionne . Cela fonctionne parce que je le teste manuellement.
Je tiens également à préciser que je ne renonce pas non plus à tous les tests automatisés. C'est là que mon processus est différent. Et c'est pourquoi je pose cette question.
TDD en théorie. Pas en pratique.
Mon processus a un peu évolué et j'ai trouvé un équilibre entre TDD et aucun test que je trouve très productif et aussi raisonnablement sûr. Il se déroule comme suit:
- Implémentez une tranche de travail verticale de travail avec des tests à l'esprit, mais n'écrivez aucun test.
- Si en cours de route (par exemple, un mois plus tard) cette tranche doit être modifiée
- Écrire des tests unitaires, des tests d'intégration, des tests de comportement, etc. qui garantissent que la tranche de travail est correcte
- Modifier le code
- Si cette tranche n'a pas besoin d'être modifiée,
- Ne fais rien
En déplaçant simplement le fardeau de l'écriture des tests avant d' écrire le code vers avant de modifier le code, j'ai pu produire beaucoup plus de code de travail. Et, quand je passe aux tests d'écriture, j'en écris beaucoup moins mais je couvre presque autant de terrain (ROI plus élevé).
J'aime ce processus, mais je crains qu'il ne puisse pas bien évoluer. Son succès dépend de la diligence des développeurs à écrire des tests avant de changer les choses. Et cela semble être un assez gros risque. Mais, TDD a le même risque.
Alors, est-ce que je vais aller en enfer [BT] DD, ou est-ce une forme courante de codage et de test pragmatique?
J'aimerais continuer à travailler de cette façon. Que puis-je faire pour que ce processus fonctionne à long terme?
Remarque:Je suis le seul développeur de mes projets et je suis responsable de tout: collecte des exigences, conception, architecture, tests, déploiement, etc. Je soupçonne que c'est la raison pour laquelle mon processus fonctionne.
la source
If that slice doesn't need modification
. lizkeogh.com/2012/06/24/beyond-test-driven-developmentRéponses:
Pour que le processus fonctionne à long terme, j'écrirais les tests lors de l'écriture du code.
Ce qui peut sembler contredire votre approche. Cependant, vous avez posé la question, je vais donc vous donner mon avis:
Vous n'avez pas besoin d'écrire les tests avant le code. oubliez cette pureté. Cependant, vous voulez écrire les tests à cette époque.
Une fois que vous avez fait fonctionner le code, vous l'avez légèrement modifié, vous avez éliminé quelques bogues (nous parlons ici d'une échelle de temps), vous êtes alors à un point de connaissance maximale de ce que fait le code. C'est le moment idéal pour écrire des tests qui capturent vos connaissances.
Le laisser à plus tard signifie que les connaissances diminueront (naturellement) avec le temps.
Cela signifie également que si jamais vous partez et si quelqu'un d'autre prend la relève, vous n'aurez pas la dette technique immédiate de ne pas avoir documenté (par le biais de tests) ce qui fait quoi.
Surtout, "un jour" peut ne pas venir. Vous pouvez soit être heurté par un bus, soit monter à bord pour de nouvelles aventures.
Enfin, le test manuel n'est pas évolutif et ne couvre souvent pas tous les appareils utilisés par l'utilisateur final.
la source
Bien que TDD soit difficile à mettre en œuvre à 100%, il y a une faille dans votre approche
Mettre en œuvre une tranche de travail verticale de travail
1.1 Pass 1 an ....
1.2 Un nouveau développeur commence à travailler sur le projet
Si cette tranche doit être modifiée
2.3 Analyser les noms et paramètres de la méthode de style «Clean Coding» «GetUnicorn (colourOfUnicorn)»
2.4 Lire les commentaires xml 'Obtient une licorne d'or (pour l'équitation) (obvs)'
2.5 Traquer le développeur d'origine
2.6 J'espère qu'ils se souviendront de ce que le code est censé faire
2.7 Demandez-leur de tout expliquer
Écrire des tests unitaires, des tests d'intégration, des tests de comportement, etc. qui, espérons-le, garantissent que la tranche de travail est correcte
Je pense que vous avez raison d'identifier que les tests unitaires montrent vraiment leur valeur lorsque des modifications sont nécessaires.
la source
Je suis d'accord avec Daniel Hollinrake et Ewan, que le premier point clé pour lequel votre test uniquement si modification fonctionne bien jusqu'à présent est:
et qu'un deuxième point clé probable est:
Je ne pense pas que TDD apporte un énorme gain de productivité pour les seuls programmeurs, et il ne peut pas améliorer considérablement la qualité de votre code si vous écrivez déjà un bon code propre.
Cependant, TDD améliorera sûrement la qualité du code des programmeurs pauvres / inexpérimentés / obsolètes, surtout quand vient le temps de modifier le code sans casser quoi que ce soit d'autre. Et encore plus si la personne qui modifie le code n'est pas la même personne qui a écrit le code à l'origine ou plusieurs mois se sont écoulés entre les deux.
En d'autres termes, je pense que TDD est à la fois une bonne pratique pour améliorer la qualité de votre code (comme vous le reconnaissez) mais aussi (et plus important) une sorte de haie lorsque vous travaillez avec des programmeurs moyens ou médiocres (disons, d'un autre département ou une autre entreprise) qui est une situation beaucoup plus courante que de travailler en solo.
la source
Pour moi, l'élément clé semble être le suivant:
Cela fonctionne pour vous et vous produisez un joli code propre (je suppose!). La seule chose que je dirais que vous devez faire est de créer un faisceau de test afin que d'autres développeurs puissent intervenir et être confiants dans les changements. Le faisceau de test garantit également la cohérence du comportement du code.
Je pense que votre approche est similaire à la mienne. Je suis généralement le seul développeur de mes projets. J'ai trouvé qu'une appréciation de TDD m'a permis d'écrire des fonctions plus petites et un code plus propre, mais j'ajoute des tests tout en écrivant le code comme un harnais de test. De cette façon, à mesure que le code évolue et que les fonctionnalités changent, je peux être assez confiant pour apporter des modifications.
Une raison secondaire pour écrire des tests est que je pense qu'ils sont une forme de documentation. Ils peuvent expliquer mes raisons derrière la création d'une fonction. Mais ici, je pense plus au développement axé sur le comportement.
la source
Les tests unitaires visent à résoudre le problème de la maintenance du code. Bien qu'il y ait des gens qui disent qu'ils écrivent plus rapidement du code avec TDD plutôt que sans, je ne suis pas surpris que vous puissiez écrire plus de nouveau code sans écrire de tests.
Les problèmes que je peux voir avec la pratique d'écrire des tests juste avant de le changer:
J'ai souvent besoin de faire des changements rapidement
Bien que vous puissiez gagner du temps dans l'ensemble en n'écrivant les tests que lorsque vous en avez besoin, tout le temps n'est pas égal. Passer 2 heures à écrire des tests pour gagner 1 heure lorsque je suis en mode crise - ça vaut vraiment le coup.
Il est plus facile d'écrire des tests en même temps que j'écris le code
Pour écrire correctement des tests unitaires, vous devez comprendre le code que je teste. J'utilise souvent les tests unitaires comme un exercice de compréhension, mais les tests unitaires du code existant peuvent prendre du temps car la compréhension du code existant prend du temps. Comparez cela à l'écriture de tests lorsque vous écrivez le code et vous le trouverez beaucoup plus rapide car vous comprenez déjà le code - vous venez de l'écrire!
La définition de Michael Feathers du code hérité est du code sans test. Peu importe si vous êtes d'accord avec sa définition, il est clair qu'une partie substantielle du coût de la modification du code existant fait en sorte qu'il fonctionne toujours comme prévu, souvent ce n'est même pas clair quel est le comportement attendu.
L'écriture de tests unitaires compense ce coût en codant une compréhension de ce qu'est le comportement correct, ainsi qu'en fournissant un moyen facile pour "nous futurs" de vérifier que le comportement est toujours correct.
la source
C'est une bonne question, et FWIW je vais jeter mes deux cents.
Il y a environ un an, je codais dans Salesforce, une plateforme qui avait un mécanisme enraciné qui vous obligeait à ne pas nécessairement écrire des tests avant de coder , mais vous obligeait plutôt à écrire des tests en général.
La façon dont cela fonctionnait était que le système vous obligerait à écrire des tests, et il ferait un calcul du nombre de lignes de votre code qui ont été testées en pourcentage. Si tout le code de votre instance de production est tombé en dessous de 75%, testé. Salesforce n'a plus de travail.
Le résultat final était que chaque fois que vous faisiez quelque chose dans Salesforce, vous deviez écrire ou mettre à jour des tests. Bien que je sois sûr que cela a un impact énorme sur la part de marché de Salesforce, en termes de vie d'un développeur, c'était une énorme douleur au cul .
La plupart du temps, vous essayiez simplement de passer à travers un petit ticket, puis les tests arrivent et doublent votre temps de développement, pour une fonctionnalité que vous savez fonctionner.
Puis le concept maladroit de TDD a balayé notre département, jusque dans nos bases de données. Nos architectes ont voulu pousser des tests approfondis dans tous les aspects de notre service informatique. Légère douleur dans le cul, rencontre une douleur encore plus grande dans le cul.
À l'époque, TDD n'avait jamais vraiment de sens pour moi, et même maintenant, cela ne fonctionne toujours pas. Une grande partie des fonctionnalités que j'ai écrites dans mon rôle actuel se déroule dans un mécanisme similaire à celui que vous avez mentionné: dans des tranches verticales que j'affine jusqu'à ce qu'elles fonctionnent. Quand j'étais dans cet ancien rôle, et encore maintenant, je ne sais souvent pas ce que mon code va faire jusqu'à ce que je l'écrive , donc l'idée que je peux écrire des tests pour piloter le code que je vais écrire juste. . n'a pas de sens pour moi, est lourd et surtout une perte de temps.
Cela dit, les tests sont des choses merveilleuses et magiques qui font tout bien dans le monde . Ils rendent votre code correct, ils garantissent que votre application fait ce que vous pensez qu'elle fait, et généralement tout est plus fluide. La question n'est alors pas de savoir si vous écrivez vos tests avant de coder, ou après avoir codé, la question est de savoir combien de temps allez-vous consacrer aux tests. C'est le vrai problème, du moins dans mon expérience de développement logiciel. Les tests prennent du temps et de l'argent et vous devez le faire dans le cadre d'intérêts concurrents.
Et donc, en général, je suis d'accord avec vous: le TDD dans la pratique est un peu maladroit et encombrant. À ce stade, vous devez garder à l'esprit ce qui fonctionne le mieux dans votre situation actuelle . Si vous écrivez du code critique, assurez-vous simplement qu'il est testé en général. Si vous avez le temps, essayez TDD et voyez si cela ajoute quelque chose au processus.
la source
Je ne pourrais pas recommander votre approche.
Si j'utilise votre approche, ce serait par exemple comme ceci (la maison est l'application):
Votre approche coûte donc beaucoup de temps et de connaissances avant de construire la maison avec votre approche. Ou cela prend beaucoup de temps! De plus, il n'est pas joli Gentleman de laisser d'autres tests d'écriture pour votre code lorsque les exigences ont changé.
Il y a donc une meilleure approche sans programmer un "prototype" et que de commencer le refactoring. Au lieu de programmer un prototype "faites un Design avec UML de votre Application comme suit.
Bien sûr, cette approche nécessite également des connaissances en UML, mais elle est rapide à apprendre. Et il est toujours plus rapide de renommer une classe ou de déplacer des flèches dans un digramme que de le faire dans votre IDE. Mais apprendre à utiliser des frameworks de test sera plus épuisant au début. Le mieux est ici de regarder exécuter des tests de projets open source et de voir comment ils fonctionnent. Mais lorsque vous utilisez une application pilotée par les tests, la prochaine application sera beaucoup plus rapide. Et je pense que c'est un bon sentiment de savoir que tout fonctionne bien.
Je vote donc vers le bas les approches parce qu'elles prennent beaucoup de temps pour les débutants et pas bon après tout. Pour avoir des frontières propres entre votre structure et le comportement, vous pouvez utiliser la conception pilotée par domaine et sous Arranger très domaine avec deux packages (un package nommé structure et l'autre comportement nommé). Aussi pour vos tests. exemple simple consultez cet exemple écrit en java.
la source
Avez-vous testé manuellement toutes les branches possibles de vos conditions après peu de changements? Combien de temps prend la boucle de rétroaction de vos tests manuels. La proximité de la boucle de rétroaction que vous obtenez avec les tests automatisés.
Les tests automatisés (peu importe le test d'abord ou non) vous permettent d'aller vite - en fournissant une boucle de rétroaction plus rapide sur votre code.
Êtes-vous sûr de ne pas oublier de tester une condition manuellement après six mois - veuillez ne pas dire que vous documenterez toutes les conditions importantes à tester - car écrire le type de documentation / commentaire équivaut à écrire le test (documentation exécutable)
Et encore une fois: lors du refactoring, avez-vous testé manuellement toute la logique affectée par le refactoring? Combien de temps faut-il pour tester le changement de refactorisation? Si la refactorisation rompt un code, combien de temps vous faut-il pour trouver une raison aux ruptures?
Le code beau et propre que vous avez apprécié est très subjectif. Votre code peut être propre et raisonnable pour vous. La meilleure méthode pour vérifier si votre code est vraiment lisible, compréhensible et testable est les tests et les révisions de code effectués par d'autres développeurs.
Vous avez trouvé votre chemin très productif uniquement parce que vous êtes uniquement développeur travaillant avec le code, et, je pense, parce que vous ne commencez à travailler que sur ce projet (quel âge ce projet sur lequel vous travaillez? 6 - 8 mois?).
Vous vous souvenez toujours de tout ce que vous avez écrit et vous pouvez reconnaître une raison pour d'éventuels problèmes. Je suis sûr que vous commencerez à écrire des tests à partir du début après 2 à 3 ans de votre projet - parce que vous voulez être sûr de ne rien oublier.
la source
Si vous ne faites jamais d'erreurs, vous n'avez pas vraiment besoin de tests. La plupart des développeurs font des erreurs, mais si vous ne le faites jamais et que vous êtes sûr de ne jamais faire d'erreurs à l'avenir (et que vous êtes le seul sur le projet), il n'y a vraiment aucune raison de perdre du temps à écrire des tests.
Mais votre solution est à mi-chemin, car vous proposez d'écrire des tests lors du changement de code, mais en même temps, votre méthode suppose que vous ne ferez jamais d'erreurs lorsque vous déciderez des parties du code pour lesquelles écrire des tests. Cela ne fonctionne que si vous comprenez toujours parfaitement les zones qu'un changement peut affecter. Je pense que de nombreux développeurs communs (pas vous bien sûr!) Ont expérimenté un changement, puis un test quelque part inattendu échoue, car vous avez fait une erreur.
Bien sûr, une bonne architecture, des principes SOLID, etc. devraient empêcher cela, mais la plupart des développeurs ne sont pas parfaits, et c'est pourquoi les tests à travers le système sont précieux.
la source