TDD vs tests unitaires [fermé]
Ma société est assez nouvelle dans le test unitaire de notre code. Je lis depuis un certain temps sur le TDD et les tests unitaires et je suis convaincu de leur valeur. J'ai essayé de convaincre notre équipe que TDD vaut la peine d'apprendre et de changer nos mentalités sur la façon dont nous programmons, mais c'est une lutte. Ce qui m'amène à ma question(s).
Il y a beaucoup dans la communauté TDD qui sont très religieux à propos de l'écriture du test puis du code (et je suis avec eux) , mais pour une équipe qui se débat avec TDD est-ce qu'un compromis apporte encore des avantages supplémentaires?
Je peux probablement réussir à amener l'équipe à écrire des tests unitaires une fois que le code est écrit (peut - être comme une exigence pour vérifier le code) et mon hypothèse est qu'il y a encore de la valeur à écrire ces tests unitaires.
Quelle est la meilleure façon d'amener une équipe en difficulté dans TDD? Et à défaut cela vaut-il toujours la peine d'écrire des tests unitaires même si c'est après l'écriture du code?
Modifier
Ce que j'ai loin de cela, il est important pour nous de commencer les tests unitaires, quelque part dans le processus de codage. Pour ceux de l'équipe qui ramassent le concept, commencer à se déplacer plus vers TDD et tester d'abord. Merci pour la contribution de tout le monde.
SUIVI
Nous avons récemment commencé un nouveau petit projet et une petite partie de l'équipe a utilisé TDD, le reste a écrit des tests unitaires après le code. Après avoir terminé la partie de codage du projet, ceux qui écrivent des tests unitaires après le code nous avons été surpris de voir les codeurs TDD déjà fait et avec du code plus solide. C'était un bon moyen de gagner les sceptiques. Nous avons encore beaucoup de douleurs de croissance à venir, mais la bataille des volontés semble être terminée. Merci pour tous ceux qui ont offert des conseils!
17 réponses
Si l'équipe patauge dans l'implémentation de TDD, mais qu'elle ne créait pas de Tests unitaires auparavant...ensuite, démarrez-les en créant des Tests unitaires après l'écriture de leur code. Même les tests unitaires écrits après le code sont meilleurs que pas de Tests unitaires du tout!
Une fois qu'ils maîtrisent les tests unitaires (et tout ce qui l'accompagne), vous pouvez travailler pour les amener à créer les tests en premier...et code deuxième.
Cela vaut absolument la peine d'écrire les tests unitaires après l'écriture du code. C'est juste que parfois c'est souvent plus difficile parce que votre code n'a pas été conçu pour être testable, et vous pouvez l'avoir trop compliqué.
Je pense qu'une bonne façon pragmatique d'amener une équipe dans TDD est de fournir la méthode alternative de "test-pendant le développement" dans la période de transition, ou éventuellement à long terme. Ils devraient être encouragés à des sections de code TDD qui leur semblent naturelles. Toutefois, dans sections de code qui semblent difficiles à aborder test-d'abord ou lors de l'utilisation d'objets prédéterminés par un processus a&D non agile, les développeurs peuvent avoir la possibilité d'écrire une petite section du code, puis d'écrire des tests pour couvrir ce code, et de répéter ce processus. Écrire des tests unitaires pour un code immédiatement après avoir écrit ce code vaut mieux que ne pas écrire de tests unitaires du tout.
Il est à mon humble avis préférable d'avoir une couverture de test de 50% avec "code d'abord, test après" et une bibliothèque terminée à 100%, que la couverture de test de 100% et une bibliothèque terminée à 50% avec TDD. Après un certain temps, vos collègues développeurs trouveront, espérons-le, amusant et éducatif d'écrire des tests pour tout le code public
qu'ils écrivent, de sorte que TDD se faufilera dans leur routine de développement.
Je viens de lire ceci sur un calendrier: "chaque règle, exécutée à son maximum, devient ridicule ou même dangereuse."Donc, ma suggestion est de ne pas être religieux à ce sujet. Chaque membre de votre équipe doit trouver un équilibre entre ce qu'il se sent "juste" en matière de tests. De cette façon, chaque membre de votre équipe sera le plus productif (au lieu, disons, de penser "Pourquoi dois-je écrire ce test sti****??").
Donc certains tests sont meilleurs que none, les tests après le code sont meilleurs que quelques tests et tester avant le code est mieux qu'après. Mais chaque étape a ses propres mérites et vous ne devriez pas froncer les sourcils même de petites étapes.
TDD est sur le design! Donc, si vous l'utilisez, vous serez sûr d'avoir une conception testable de votre code, ce qui facilite l'écriture de vos tests. Si vous écrivez des tests après l'écriture du code, ils sont toujours précieux mais à mon humble avis, vous perdrez du temps puisque vous n'aurez probablement pas de conception testable.
Une suggestion que je peux vous donner pour essayer de convaincre votre équipe d'adopter TDD est d'utiliser certaines des techniques décrites sur Mary Linn et Linda Rising book: Patterns for Présentation de nouvelles idées
S'ils sont nouveaux dans les tests que IMO commencent à tester le code qui a déjà été écrit et passent lentement à l'écriture des tests en premier. En tant que quelqu'un essayant d'apprendre le TDD et nouveau aux tests unitaires, j'ai trouvé difficile de faire un 180 complet et de changer d'état d'esprit pour écrire des tests avant le code, donc l'approche que je prends est une sorte de mélange 50-50; quand je sais exactement à quoi ressemblera le code, je vais écrire le code et ensuite écrire un test pour le vérifier. Pour les situations où je ne suis pas tout à fait sûr alors Je vais commencer par un test et travailler mon chemin vers l'arrière.
Rappelez-vous également qu'il n'y a rien de mal à écrire des tests pour vérifier le code, au lieu d'écrire du code pour satisfaire les tests. Si votre équipe ne veut pas suivre la route TDD, ne le forcez pas sur eux.
Je peux probablement réussir à amener l'équipe à écrire des tests unitaires une fois que le code est écrit (peut - être comme une exigence pour vérifier le code) et mon hypothèse est qu'il y a encore de la valeur à écrire ces tests unitaires.
Il n'y a absolument aucun doute sur le fait qu'il y a une valeur dans le code testé par unité (indépendamment du moment où les tests ont été écrits) et j'inclus "le code est testé par unité" dans la "définition de Done". Les gens peuvent utiliser TDD ou non, tant qu'ils test.
En ce qui concerne le contrôle de version, j'aime utiliser "branches de développement " avec une unité testée Politique (IE le code compile et construit, tous les tests unitaires passent). Lorsque les fonctionnalités sont terminées,elles sont publiées depuis les branches de développement vers le tronc. En d'autres termes, la branche trunk est la "Done branch" (Pas d'ordure sur le tronc!) et a une shippable Politique (peut libérer à tout moment) qui est plus stricte et comprend plus de choses que "unité testée".
C'est quelque chose avec lequel votre équipe devra avoir ses propres succès avant de commencer à y croire. Je vais diatribe à propos de mon épiphanie nUnit pour tous ceux qui se soucient:
Il y a environ 5 ans, j'ai découvert nUnit en travaillant sur un projet. Nous avions presque terminé V1.0 et j'ai créé quelques tests juste pour essayer ce nouvel outil. Nous avons eu beaucoup de bugs (évidemment!) parce que nous étions une nouvelle équipe, sur un délai serré, des attentes élevées (son familier?) etc. Quoi qu'il en soit nous avons obtenu 1.0 et a commencé 1.1. Nous avons ré-organisé l'équipe un peu et j'ai reçu 2 devs assignés à moi. J'ai fait une démo de 1 heure pour eux et leur ai dit que tout ce que nous avons écrit devait avoir un cas de test avec. Nous avons constamment couru "derrière" le reste de l'équipe pendant le cycle de développement 1.1 parce que nous écrivions plus de code, les tests unitaires. Nous avons fini par travailler plus Mais voici le gain-quand nous avons finalement commencé à tester, nous avions exactement 0 bugs dans notre code. Nous avons aidé tout le monde à déboguer et à réparer leurs bugs. Dans le post-mortem, lorsque le nombre de bugs est apparu, il a attiré L'attention de tout le monde.
Je ne suis pas assez stupide pour penser que vous pouvez tester votre chemin vers le succès, mais je suis un vrai croyant quand il s'agit de tests unitaires. Le projet a adopté nUnit et il s'est rapidement étendu à l'entreprise pour tous les projets. net à la suite du succès 1. La période de temps totale pour notre version v1.1 était de 9 semaines de développement, Donc ce n'était certainement pas un succès du jour au lendemain. Mais à long terme, il s'est avéré un succès pour notre projet et l'entreprise pour laquelle nous avons construit des solutions.
Il ne fait aucun doute que les tests (D'abord, pendant ou même après) sauveront votre bacon et amélioreront votre productivité et votre confiance. Je recommande de l'adopter!
J'étais dans une situation similaire, parce que j'étais un développeur "noob", j'étais souvent frustré quand je travaillais sur un projet d'équipe par le fait qu'une contribution avait brisé la construction. Je ne savais pas si j'étais à blâmer ou même, dans certains cas, qui blâmer. Mais j'étais plus préoccupé que je faisais la même chose à mes collègues développeurs. Ce la réalisation a ensuite motivé l'adoption de certaines stratégies de TDD. Notre équipe a commencé à avoir des jeux stupides, et des règles, comme vous ne pouvez pas rentrer à la maison jusqu'à ce que tous vos tests passent, ou si vous soumettez quelque chose sans test, alors vous devez acheter tout le monde "bière/déjeuner/etc" et cela a rendu TDD plus amusant.
L'un des aspects les plus utiles des tests unitaires est d'assurer l'exactitude continue du code qui fonctionne déjà. Lorsque vous pouvez refactoriser à volonté, laissez un IDE vous rappeler des erreurs de compilation, puis cliquez sur un bouton pour laisser vos tests repérer les erreurs d'exécution potentielles-arrivant parfois dans des blocs de code précédemment triviaux, alors je pense que votre équipe commence à apprécier TDD. Donc, commencer par tester le code existant est certainement utile.
Aussi, pour être franc, j'ai en savoir plus sur la façon d'écrire du code testable en essayant de tester le code écrit que de commencer avec TDD. Cela peut être trop abstrait au début si vous essayez de penser à des contrats qui permettront à la fois d'atteindre l'objectif final et de permettre les tests. Mais quand vous regardez le code et que vous pouvez dire "ce singleton gâche complètement l'injection de dépendance et rend le test impossible", vous commencez à développer une appréciation de ce que les modèles rendent votre vie de test plus facile.
Eh bien, si vous n'écrivez pas les premiers tests, ce n'est pas" Test Driven", c'est juste des tests. Il a des avantages en soi et si vous avez déjà une base de code ajoutant des tests pour cela est certainement utile même si ce n'est pas TDD mais simplement tester.
L'écriture de tests consiste d'abord à se concentrer sur ce que le code doit faire avant de l'écrire. Oui, vous obtenez également un test faisant cela et c'est bien, mais certains peuvent prétendre que ce n'est même pas le point le plus important.
Ce que je ferais est de former l'équipe sur jouet des projets comme ceux-ci (Voir Coding Dojo, Katas) en utilisant TDD (si vous pouvez obtenir des programmeurs TDD expérimentés pour participer à un tel atelier, ce serait encore mieux). Quand ils verront les avantages qu'ils utiliseront TDD pour le vrai projet. Mais pendant ce temps ne les forcez pas, ils ne voient pas le bénéfice qu'ils ne le feront pas correctement.
Si vous avez des sessions de conception avant d'écrire du code ou que vous devez produire un document de conception, vous pouvez ajouter des Tests unitaires comme résultat tangible d'une session.
Cela pourrait alors servir de spécification sur le fonctionnement de votre code. Encouragez l'appariement lors de la session de conception, pour amener les gens à parler de la façon dont quelque chose devrait fonctionner et de ce qu'il devrait faire dans des scénarios donnés. Quels sont les cas de bord, avec des cas de test explicites pour eux afin que tout le monde sache ce qu'il va faire si on leur donne un null argument par exemple.
Un côté mais BDD peut également être d'intérêt
Vous pouvez trouver une certaine traction en montrant un exemple ou deux où TDD entraîne moins de code à écrire-parce que vous écrivez seulement le code requis pour réussir le test, la tentation d'or-plaque ou de s'engager dans YAGNI est plus facile à résister. Le Code que vous n'écrivez pas n'a pas besoin d'être maintenu, refactorisé, etc., donc c'est une "économie réelle" qui peut aider à vendre le concept de TDD.
Si vous pouvez démontrer clairement la valeur en termes de temps, de coût, de code et de bogues enregistrés, vous trouverez peut-être que c'est plus facile vendre.
Commencer à construire des classes de test JUnit est la façon de commencer, pour le code existant, c'est la seule façon de commencer. Dans mon expérience, il est très utile de créer des classes de test pour le code existant. Si la direction pense que cela va investir trop de temps, vous pouvez proposer d'écrire uniquement des classes de test lorsque la classe correspondante contient un bogue ou a besoin d'un nettoyage.
Pour le processus de maintenance, l'approche pour faire passer l'équipe au-dessus de la ligne serait d'écrire des tests JUnit pour reproduire des bogues avant de les réparer, c'est-à-dire
- bug est signalé
- créez une classe de test JUnit si nécessaire
- ajouter un test qui reproduit le bogue
- corrigez votre code
- exécutez le test pour montrer que le code actuel ne reproduit pas le bogue
Vous pouvez expliquer qu'en "documentant" les bogues de cette manière, ils empêcheront ces bogues de revenir plus tard. C'est un avantage que l'équipe peut éprouver immédiatement.
Je l'ai fait dans de nombreuses organisations et j'ai trouvé le meilleur moyen de démarrer et de suivre TDD est de configurer la programmation par paires. Si vous avez quelqu'un d'autre sur qui vous pouvez compter qui connaît TDD, alors vous pouvez vous séparer et vous associer à d'autres développeurs pour faire de la programmation appariée en utilisant TDD. Sinon, je formerais quelqu'un qui vous aidera à le faire avant de le présenter au reste de l'équipe.
L'un des principaux obstacles avec les tests unitaires et en particulier TDD est que les développeurs ne savent pas comment le faire, donc ils ne peuvent pas voir comment il peut être utile de leur temps. Aussi, lorsque vous commencez, il est beaucoup plus lent et ne semble pas fournir des avantages. Il est seulement vraiment vous fournir des avantages quand vous êtes bon à elle. En configurant des sessions de programmation jumelées, vous pouvez rapidement amener les développeurs à l'apprendre rapidement et à y arriver plus rapidement. En outre, ils seront en mesure de voir les avantages immédiats que vous travaillez bien ensemble.
Ce approche a travaillé plusieurs fois pour moi dans le passé.
Un moyen puissant de découvrir les avantages de TDD est de faire une réécriture significative de certaines fonctionnalités existantes, peut-être pour des raisons de performance. En créant une suite de tests qui font un bon travail couvrant toutes les fonctionnalités du code existant, cela vous donne alors la confiance de refactoriser au contenu de votre cœur en toute confiance que vos changements sont sûrs.
Notez que dans ce cas, je parle de tester les tests de conception ou de contrat - unité qui testent l'implémentation les détails ne seront pas appropriés ici. Mais là encore, TDD ne peut pas tester l'implémentation par définition, car ils sont censés être écrits avant l'implémentation.
TDD est un outil que les développeurs peuvent utiliser pour produire un meilleur code. Je pense que l'exercice d'écriture de code testable est aussi précieux que les tests eux-mêmes. Isoler L'IUT (implémentation sous Test) à des fins de test a l'effet secondaire de découpler votre code.
TDD n'est pas pour tout le monde, et il n'y a pas de magie qui amènera une équipe à choisir de le faire. Le risque est que les auteurs de tests unitaires qui ne savent pas ce qui vaut la peine d'être testés écriront beaucoup de tests de faible valeur, ce qui sera de la chair à canon pour les sceptiques du TDD dans votre organisation.
Je fais généralement des Tests d'acceptation automatisés non négociables, mais permet aux développeurs d'adopter TDD comme il leur convient. J'ai mes TDDers expérimentés train / mentor le reste et "prouver" l'utilité par l'exemple sur une période de plusieurs mois.
Il s'agit autant d'un changement social/culturel que d'un changement technique.