J'ai seulement 2+ années d'expérience dans le développement d'applications. Au cours de ces deux années, mon approche du développement a été la suivante
- Analyser les exigences
- Composant / Objets Identity Core, Fonctions requises, Comportement, Processus et leurs contraintes
- Créer des classes, relation entre elles, contraintes sur le comportement et les états des objets
- Créer des fonctions, traiter avec des contraintes comportementales selon les exigences
- Tester l'application manuellement
- Si les modifications des exigences modifient le composant / les fonctions, testez l'application manuellement
Récemment, j'ai été initié à TDD et je pense que c'est un très bon moyen de faire du développement car le code développé a de bonnes raisons d'exister et de nombreux problèmes de post-déploiement sont atténués.
Mais mon problème est que je ne suis pas en mesure de créer des tests en premier, j'identifie plutôt les composants et j'écris simplement des tests pour eux avant d'écrire des composants. Ma question est
- Suis-je en train de faire c'est bien? Si ce n'est pas exactement ce que je dois changer
- Existe-t-il un moyen d'identifier si le test que vous avez écrit est suffisant?
- Est-ce une bonne pratique d'écrire un test pour une fonctionnalité très simple qui pourrait être équivalente à 1 + 1 = 2 ou est-ce juste une surexposition?
- Est-il bon de changer la fonctionnalité et de tester en conséquence si les exigences changent?
Réponses:
C'est difficile à dire juste à partir de cette courte description, mais je soupçonne que non, vous ne le faites pas correctement. Remarque: Je ne dis pas que ce que vous faites ne fonctionne pas ou est en quelque sorte mauvais, mais vous ne faites pas TDD. Le milieu "D" signifie "Driven", les tests pilotent tout, le processus de développement, le code, la conception, l'architecture, tout .
Les tests vous disent quoi écrire, quand l'écrire, quoi écrire ensuite, quand arrêter d'écrire. Ils vous disent le design et l'architecture. (La conception et l'architecture émergent du code par le refactoring.) TDD n'est pas une question de test. Il ne s'agit même pas d'écrire des tests d'abord: TDD consiste à laisser les tests vous guider, les écrire d'abord n'est qu'une condition préalable nécessaire pour cela.
Peu importe que vous écriviez réellement le code ou que vous le développiez complètement: vous écrivez (des squelettes de) code dans votre tête, puis écrivez des tests pour ce code. Ce n'est pas TDD.
Abandonner cette habitude est difficile . Vraiment, vraiment dur. Cela semble être particulièrement difficile pour les programmeurs expérimentés.
Keith Braithwaite a créé un exercice qu'il appelle TDD comme si vous le vouliez . Il consiste en un ensemble de règles (basées sur les trois règles de l'oncle Bob Martin sur le TDD , mais beaucoup plus strictes) que vous devez suivre strictement et qui sont conçues pour vous orienter vers une application plus rigoureuse du TDD. Cela fonctionne mieux avec la programmation en binôme (pour que votre binôme s'assure que vous ne violez pas les règles) et un instructeur.
Les règles sont les suivantes:
Typiquement, cela conduira à des conceptions très différentes de la "méthode pseudo-TDD" souvent utilisée pour "imaginer dans votre tête ce que devrait être la conception, puis écrire des tests pour forcer cette conception, implémenter la conception que vous aviez déjà envisagée avant d'écrire votre tests ".
Lorsqu'un groupe de personnes implémente quelque chose comme un jeu de tic tac toe utilisant un pseudo-TDD, ils se retrouvent généralement avec des conceptions très similaires impliquant une sorte de
Board
classe avec un tableau 3 × 3 deInteger
s. Et au moins une partie des programmeurs auront en fait écrit cette classe sans tests car ils "savent qu'ils en auront besoin" ou "auront besoin de quelque chose pour écrire leurs tests". Cependant, lorsque vous forcez ce même groupe à appliquer TDD comme si vous le vouliez, ils se retrouveront souvent avec une grande diversité de conceptions très différentes, n'utilisant souvent rien de même à distance similaire à aBoard
.Quand ils couvrent tous les besoins de l'entreprise. Les tests sont un codage des exigences du système.
Encore une fois, vous l'avez à l'envers: vous n'écrivez pas de tests de fonctionnalité. Vous écrivez des fonctionnalités pour les tests. Si la fonctionnalité permettant de réussir le test s'avère insignifiante, tant mieux! Vous venez de remplir une exigence système et n'avez même pas eu à travailler dur pour cela!
Non. L'inverse. Si une exigence change, vous modifiez le test qui correspond à cette exigence, regardez-le échouer, puis changez le code pour le faire passer. Les tests viennent toujours en premier.
C'est difficile à faire. Vous avez besoin de dizaines, peut-être de centaines d'heures de pratique délibérée pour construire une sorte de "mémoire musculaire" pour arriver à un point où, lorsque la date limite approche et que vous êtes sous pression, vous n'avez même pas besoin d'y penser , et cela devient le moyen de travail le plus rapide et le plus naturel.
la source
Board
classe avec un Tableau 3x3 deint
s (ou quelque chose comme ça). Alors que si vous les forcez à faire TDDAIYMI, ils finissent souvent par créer une mini-DSL pour capturer les connaissances du domaine. C'est juste anecdotique, bien sûr. Une étude statistiquement et scientifiquement valable serait bien, mais comme c'est souvent le cas avec des études comme celle-ci, elles sont soit trop petites, soit beaucoup trop chères.Vous décrivez votre approche de développement comme un processus «de haut en bas uniquement» - vous partez d'un niveau d'abstraction plus élevé et allez de plus en plus dans les détails. Le TDD, du moins sous sa forme courante, est une technique "ascendante". Et pour quelqu'un qui travaille principalement «de haut en bas», il peut en effet être très inhabituel de travailler «de bas en haut».
Alors, comment pouvez-vous apporter plus de "TDD" dans votre processus de développement? Tout d'abord, je suppose que votre processus de développement réel n'est pas toujours aussi «descendant» que vous l'avez décrit ci-dessus. Après l'étape 2, vous aurez probablement identifié certains composants qui sont indépendants des autres composants. Parfois, vous décidez de mettre en œuvre ces composants en premier. Les détails de l'API publique de ces composants ne suivent probablement pas seuls vos besoins, les détails suivent également vos décisions de conception. C'est le point où vous pouvez commencer avec TDD: imaginez comment vous allez utiliser le composant et comment vous allez réellement utiliser l'API. Et lorsque vous commencez à coder une telle utilisation de l'API sous forme de test, vous venez de commencer avec TDD.
Deuxièmement, vous pouvez faire du TDD même lorsque vous allez coder davantage "de haut en bas", en commençant par les composants qui dépendent d'abord d'autres composants non existants. Ce que vous devez apprendre, c'est d'abord comment "simuler" ces autres dépendances. Cela vous permettra de créer et de tester des composants de haut niveau avant de passer aux composants de niveau inférieur. Un exemple très détaillé sur la façon de faire TDD de haut en bas peut être trouvé dans ce blog de Ralf Westphal .
la source
Tu vas très bien.
Oui, utilisez un outil de couverture de test / code . Martin Fowler offre de bons conseils sur la couverture des tests.
En général, toute fonction, méthode, composant, etc. qui devrait donner des résultats compte tenu de certaines entrées est un bon candidat pour un test unitaire. Cependant, comme avec la plupart des choses dans la vie (d'ingénierie), vous devez considérer vos compromis: l'effort est-il compensé en écrivant le test unitaire résultant en une base de code plus stable à long terme? En général, choisissez d'abord d'écrire du code de test pour les fonctionnalités cruciales / critiques. Plus tard, si vous trouvez qu'il y a des bogues associés à une partie non testée du code, ajoutez d'autres tests.
La bonne chose à propos des tests automatisés est que vous verrez immédiatement si un changement rompt les assertions précédentes. Si vous vous y attendez en raison des exigences modifiées, oui, il est correct de changer le code de test (en fait, en TDD pur, vous changeriez d'abord les tests en fonction des exigences, puis adopteriez le code jusqu'à ce qu'il réponde aux nouvelles exigences).
la source
L'écriture des tests d'abord est une approche complètement différente de l'écriture de logiciels. Les tests ne sont pas seulement un outil de vérification de la fonctionnalité du code approprié (ils réussissent tous), mais la force qui définit la conception. Bien que la couverture des tests puisse être une mesure utile, elle ne doit pas être l'objectif en soi - l'objectif de TDD n'est pas d'atteindre un bon% de couverture de code, mais de réfléchir à la testabilité de votre code avant de l'écrire.
Si vous rencontrez des problèmes pour écrire des tests en premier, je vous recommande fortement de faire une session de programmation par paires avec une personne expérimentée en TDD, afin de vous familiariser avec "la façon de penser" de toute l'approche.
Une autre bonne chose à faire est de regarder une vidéo en ligne où un logiciel est développé en utilisant TDD dès la première ligne de celui-ci. Le bon que j'ai utilisé pour me présenter au TDD était Let's Play TDD de James Shore. Jetez un coup d'œil, il illustrera comment fonctionne la conception émergente, quelles questions devez-vous vous poser lors de l'écriture de tests et comment de nouvelles classes et méthodes sont créées, refactorisées et itérées.
Je pense que ce n'est pas la bonne question à poser. Lorsque vous faites du TDD, vous avez choisi de faire du TDD et de la conception émergente pour écrire des logiciels. Si une nouvelle fonctionnalité que vous devez ajouter commence toujours par un test, elle sera toujours là.
Évidemment, cela dépend, utilisez votre jugement. Je préfère ne pas écrire de tests sur les paramètres de contrôles nuls, si la méthode ne fait pas partie de l'API publique, mais sinon, pourquoi ne confirmeriez-vous pas que la méthode Add (a, b) renvoie effectivement a + b?
Encore une fois, lorsque vous modifiez ou ajoutez de nouvelles fonctionnalités à votre code, vous commencez par un test, qu'il s'agisse d'ajouter un nouveau test ou d'en modifier un existant lorsque les exigences changent.
la source