Préface
Le développement piloté par les tests est une façon de gérer la peur pendant la programmation.
Kent Beck
Nous avons une chance ineffable ! Cela fait des années que nous avons un développement piloté par les tests.
Plusieurs décennies se sont écoulées depuis que les développeurs qui ont écrit le code du programme spatial Mercury ont pratiqué le TDD (développement piloté par les tests) sur carte perforée. Les bibliothèques XUnit qui facilitent l'adoption du développement piloté par les tests remontent au début du siècle. En fait, Kent Beck, qui a écrit Test-Driven Development : By Example (Addison-Wesley Professional, 2002) et qui a développé le framework JUnit, se présente comme ayant "redécouvert" (et non inventé) la pratique du TDD. Cette déclaration témoigne de son humilité, mais c'est aussi la vérité. Le TDD est aussi vieux que le développement de logiciels lui-même.
Alors pourquoi le développement piloté par les tests est-il encore loin d'être la méthode standard d'écriture du code ? Pourquoi est-ce souvent la première pratique qui est sacrifiée lorsqu'il y a une pression sur le calendrier, ou lorsque les budgets informatiques doivent être réduits, ou (mon préféré) lorsqu'il y a un désir d'"augmenter la vitesse de l'équipe de livraison du logiciel" ? Toutes ces raisons sont avancées en dépit de la disponibilité de preuves empiriques et expérimentales montrant que le TDD réduit le nombre de défauts, crée une conception plus simple et améliore la confiance des développeurs dans leur propre code.
Pourquoi le TDD est-il adopté à contrecœur et abandonné avec empressement ? Les arguments suivants, souvent entendus de la part de ceux qui sont réticents à la pratiquer, peuvent expliquer pourquoi :
- Je ne sais pas où et comment commencer.
-
La raison la plus courante est peut-être le manque de sensibilisation et d'exposition. Comme toute autre compétence, écrire du code dans un style piloté par les tests est quelque chose qui doit être appris. De nombreux développeurs n'ont pas eu l'incitation externe (temps, ressources, conseils, encouragements) ou la motivation interne (surmonter sa propre réticence et sa propre peur) pour apprendre cette compétence.
- Le TDD fonctionne dans les programmes jouets ou pendant les entretiens de codage, mais pas lors de l'écriture du code du "monde réel".
-
C'est faux mais compréhensible. La plupart des tutoriels et des livres sur le développement piloté par les tests - y compris celui-ci - sont contraints de choisir des exemples relativement simples dans un domaine évident. Il est difficile d'écrire un article ou un livre sur le TDD avec le code réel d'un logiciel extrait d'une application déployée commercialement (par exemple, d'une institution financière, d'un système de gestion des soins de santé ou d'une automobile autopilotée). D'une part, une grande partie de ce code réel est propriétaire et n'est pas open source. D'autre part, c'est le travail de l'auteur de montrer le code d'un domaine qui a le plus d'attrait pour le plus grand nombre. Il serait illogique, à la limite de l'obscurantisme, de montrer le TDD dans le contexte d'un domaine hautement spécialisé. Cela nécessiterait, avant toute chose, une longue explication des arcanes du jargon et de la langue de bois de ce domaine. Cela irait à l'encontre de l'objectif même de l'auteur : rendre TDD compréhensible, abordable, voire aimable.
Malgré ces obstacles à l'utilisation de code réel dans la littérature sur le TDD, les développeurs écrivent régulièrement des logiciels de production en utilisant le développement piloté par les tests. Le meilleur exemple et le plus convaincant est peut-être la suite de tests unitaires du cadre JUnit lui-même. Le noyau Linux - peut-être le logiciel le plus utilisé au monde - est amélioré grâce aux tests unitaires.
- Écrire des tests après coup est suffisant ; le TDD est trop restrictif et/ou pédant.
-
C'est plus rafraîchissant à entendre que le discours occasionnel selon lequel "les tests unitaires sont surestimés" ! Écrire des tests après avoir écrit le code de production est une amélioration par rapport à ne pas écrire de tests du tout. Tout ce qui augmente la confiance des développeurs dans leur code, réduit la complexité accidentelle et fournit une documentation authentique est une bonne chose. Cependant, l'écriture de tests unitaires avant l' écriture du code de production fournit une fonction de forçage contre la création d'une complexité arbitraire.
Le TDD nous guide vers une conception plus simple parce qu'il fournit ces deux règles pratiques comme garde-fous :
-
N'écris du code de production que pour corriger un test qui a échoué.
-
Refondre énergiquement quand, et seulement quand, les tests sont verts.
-
Le développement piloté par les tests garantit-il que tout le code que nous écrirons jamais sera automatiquement et inévitablement le code le plus simple qui fonctionne ? Non, ce n'est pas le cas. Aucune pratique, règle, livre ou manifeste ne peut le faire. C'est aux personnes qui donnent vie à ces pratiques de s'assurer que la simplicité est atteinte et conservée.
Le contenu de ce livre explique et instruit le fonctionnement du développement piloté par les tests dans trois langages de programmation différents. Son but est d'inculquer aux développeurs l'habitude et la conviction d'utiliser le TDD comme une pratique régulière. Cet objectif est peut-être ambitieux, mais j'espère qu'il n'est pas insaisissable.
Qu'est-ce que le développement piloté par les tests ?
Le développement piloté par les tests est une technique de conception et de structuration du code qui encourage la simplicité et augmente la confiance que l'on a dans le code, même si sa taille augmente.
Voyons les différentes parties de cette définition.
Une technique
Le développement piloté par les tests est une technique. Il est vrai que cette technique est portée par un ensemble de croyances sur le code, à savoir :
-
Cette simplicité - l'art de maximiser la quantité de travail non effectué - est essentielle.1
-
Que l'évidence et la clarté sont plus vertueuses que l'astuce.
-
L'écriture d'un code clair est un élément clé de la réussite.
Bien qu'il soit ancré dans ces croyances, en pratique, le TDD est une technique. Comme faire du vélo, pétrir de la pâte ou résoudre des équations différentielles, c'est une compétence que personne ne possède à la naissance et que tout le monde doit apprendre.
À part cette section, ce livre ne s'attarde pas sur le système de croyances qui sous-tend le développement piloté par les tests. Il part du principe que tu y souscris déjà ou que tu es prêt à essayer le TDD en tant que nouvelle compétence (ou compétence oubliée).
Les mécanismes de cette technique - écrire d'abord un test unitaire qui échoue, puis écrire rapidement juste assez de code pour le faire passer, et enfin prendre le temps de nettoyer - occupent la majeure partie de ce livre. Tu auras de nombreuses occasions d'essayer cette technique pour toi-même.
En fin de compte, il est plus satisfaisant d'apprendre une compétence et de s'imprégner des croyances qui la soutiennent - tout comme il est plus agréable de faire du vélo si tu te rappelles que c'est bon pour ta santé et pour l'environnement !
Conception et structuration du code
Remarque que le TDD ne consiste pas fondamentalement à tester le code. Il est vrai que nous utilisons des tests unitaires pour piloter le code, mais le but du TDD est d'améliorer la conception et la structure du code.
Cette orientation est vitale. Si le TDD ne concernait que les tests, nous ne pourrions pas vraiment défendre efficacement l'idée d'écrire des tests avant plutôt qu'après l' écriture du code de l'entreprise. C'est l'objectif de concevoir un meilleur logiciel qui nous stimule ; les tests sont simplement un moyen de progresser. Les tests unitaires que nous obtenons grâce au TDD sont un bonus supplémentaire ; le principal avantage est la simplicité de la conception que nous obtenons.
Comment parvient-on à cette simplicité ? C'est par le mécanisme du red-green-refactor, qui est décrit en détail au début du chapitre 1.
Un parti pris pour la simplicité
La simplicité n'est pas une simple notion ésotérique. Dans les logiciels, nous pouvons la mesurer. Moins de lignes de code par fonction, moins de complexité cyclomatique, moins d'effets secondaires, moins d'exigences en matière de temps d'exécution ou de mémoire - tout sous-ensemble de ces exigences (ou d'autres) peut être considéré comme une mesure objective de la simplicité.
Le développement piloté par les tests, en nous obligeant à créer "la chose la plus simple qui fonctionne" (c'est-à-dire celle qui réussit tous les tests), nous pousse constamment vers ces paramètres de simplicité. Nous n'avons pas le droit d'ajouter du code superflu "au cas où nous en aurions besoin" ou parce que "nous pouvons le voir venir". Nous devons d'abord écrire un test qui échoue pour justifier l'écriture d'un tel code. Le fait d'écrire d'abord le test agit comme une fonction de forçage - nous obligeant à faire face à une complexité arbitraire dès le début. Si la fonction que nous sommes sur le point de développer est mal définie, ou si notre compréhension de cette fonction est imparfaite, nous aurons du mal à écrire un bon test dès le départ. Cela nous obligera à résoudre ces problèmes avant d' écrire une ligne de code de production. C'est la vertu du TDD : en exerçant la discipline qui consiste à faire passer notre code par des tests, nous éliminons la complexité arbitraire à chaque étape.
Cette vertu n'est pas mystique : l'utilisation du développement piloté par les tests ne réduira pas de moitié ton temps de développement, les lignes de code ou le nombre de défauts. Ce qu'il te permettra de faire, c'est d'arrêter la tentation d'introduire une complexité artificielle et artificielle. Le code qui en résultera - motivé par la discipline d'écrire d'abord les tests qui échouent - apparaîtra comme le moyen le plus simple de faire le travail, c'est-à-dire le code le plus simple qui réponde aux besoins des tests.
Une plus grande confiance en soi
Le code doit inspirer confiance, en particulier le code dont nous sommes les auteurs. Cette confiance, bien qu'elle soit elle-même un sentiment nébuleux, est fondée sur une attente de prévisibilité. Nous avons confiance dans les choses dont nous pouvons prévoir le comportement. Si le café du coin me facture moins cher un jour et plus cher du même montant le lendemain, je risque de perdre confiance dans le personnel, même si j'arrive à rentrer dans mes frais sur les deux jours. C'est dans la nature humaine que nous apprécions la régularité et la prévisibilité encore plus que la valeur nette. Le joueur le plus chanceux du monde, qui vient peut-être de gagner dix fois de suite à la roulette, ne dirait pas qu'il "fait confiance" ou qu'il a "confiance" en la roue. Notre affinité pour la prévisibilité survit même à la chance stupide.
Le développement piloté par les tests augmente notre confiance dans notre code parce que chaque nouveau test fait évoluer le système d'une manière nouvelle et non testée auparavant - littéralement ! Au fil du temps, la suite de tests que nous créons nous protège contre les échecs de régression.
Cette batterie de tests en constante augmentation est la raison pour laquelle, au fur et à mesure que la taille du code augmente, sa qualité et notre confiance en lui augmentent également.
À qui s'adresse ce livre ?
Ce livre s'adresse aux développeurs, c'est-à-dire aux personnes qui écrivent des logiciels.
Il existe de nombreux titres professionnels qui accompagnent cette vocation : "ingénieur logiciel", "architecte d'application", "ingénieur devops", "ingénieur en automatisation des tests", "programmeur", "hacker", "chuchoteur de code", et d'innombrables autres. Les titres peuvent être impressionnants ou humbles, branchés ou solennels, traditionnels ou modernes. Cependant, les personnes qui portent ces titres ont un point commun : elles passent au moins une partie de leur semaine - si ce n'est chaque jour - devant un ordinateur, à lire et/ou à écrire du code source.
J'ai choisi le terme de développeurs pour représenter cette communauté dont je suis un membre à la fois humble et reconnaissant.
Écrire du code est l'une des activités les plus libératrices et égalitaires que l'on puisse imaginer. En théorie, tout ce dont on a besoin en termes de prouesses physiques, c'est de posséder un cerveau. L'âge, le genre, le sexe, la nationalité, l'origine nationale - rien de tout cela ne devrait être une barrière. Avoir des handicaps physiques ne devrait pas être une barrière.
Cependant, il serait naïf de penser que la réalité est aussi nette ou juste que cela. L'accès aux ressources informatiques n'est pas équitable. Un certain niveau de richesse, de liberté et de sécurité est nécessaire. L'accès est encore plus difficile à cause de logiciels mal écrits, de matériel mal conçu et d'une myriade d'autres limitations d'utilisation qui empêchent tout le monde d'apprendre à programmer en se basant uniquement sur l'intérêt et l'effort.
J'ai essayé de rendre ce livre accessible au plus grand nombre. En particulier, j'ai essayé de le rendre accessible aux personnes souffrant d'un handicap physique. Les images ont un texte alt pour faciliter la lecture électronique. Le code est disponible sur GitHub. Et la prose est simple.
En termes d'expérience, ce livre s'adresse aussi bien aux personnes qui apprennent encore à programmer qu'à celles qui savent déjà programmer. Si tu rampes sur un (ou plusieurs) des trois langages présentés dans ce livre, tu es bien dans le public cible.
Cependant, ce livre n'enseigne pas les bases de la programmation dans n'importe quel langage, notamment Go, JavaScript ou Python. Il faut savoir lire et écrire du code dans au moins un des langages de programmation. Si tu es absolument novice en programmation, il serait judicieux de consolider les bases de l'écriture de code dans l'un des trois langages avant de poursuivre avec ce livre.
Ce livre s'adresse aux développeurs qui n'en sont plus à leurs premiers pas dans la programmation, ainsi qu'aux architectes chevronnés, comme le montre la figure P-1. (Kent Beck est un cas particulier).
Écrire du code peut être tour à tour exaltant et exaspérant. Cependant, même dans les moments les plus frustrants, il devrait toujours y avoir plus qu'une lueur d'optimisme et un boisseau de confiance dans le fait que nous pouvons faire en sorte que le code nous obéisse. Avec de la persévérance, tu verras que ton voyage à travers ce livre est fructueux et que la joie d'écrire du code en fonction des tests est une joie que tu voudras savourer longtemps après avoir fini de lire le chapitre 14.
Quelles sont les conditions préalables à la lecture de ce livre ?
En termes d'équipement et de prouesses techniques, tu devrais :
-
Avoir accès à un ordinateur avec une connectivité internet.
-
Pouvoir installer et supprimer des logiciels sur cet ordinateur. En d'autres termes, ton accès à cet ordinateur ne doit pas être limité ; dans la plupart des cas, cela nécessiterait d'avoir un accès "Administrateur" ou "Superutilisateur" sur cet ordinateur.
-
Être capable de lancer et d'utiliser un programme shell, un navigateur web, un éditeur de texte et éventuellement un environnement de développement intégré (IDE) sur cet ordinateur.
-
Avoir installé (ou être capable d'installer) les outils d'exécution pour l'un des langages utilisés dans ce livre.
-
Sois capable d'écrire et d'exécuter un programme simple - "Hello World" - dans l'un des langages utilisés dans ce livre.
Lasection "Configuration de ton environnement de développement" du chapitre 0 contient plus de détails sur l'installation.
Comment lire ce livre
Le sujet de ce livre est "comment faire du développement piloté par les tests en Go, JavaScript et Python". Bien que les concepts abordés soient applicables aux trois langages, le traitement de chaque langage nécessite une certaine séparation de la matière dans chaque chapitre. La meilleure façon d'apprendre le développement piloté par les tests (comme toute autre compétence acquise) est la pratique. Je t'encourage à lire le texte et à écrire le code par toi-même. J'appelle ce style "suivre le livre" - parce qu'il comprend une lecture active et un codage actif.
Astuce
Pour tirer le meilleur parti de ce livre, écris le code de l'exemple Money dans les trois langues.
La plupart des chapitres comportent des sections générales applicables aux trois langues. Elles sont suivies par des sections spécifiques à la langue, où le code d'une des trois langues est décrit et développé. Ces sections spécifiques à un langage sont toujours clairement identifiées par leur titre : Go, JavaScript ou Python. À la fin de chaque chapitre, une ou deux sections résument ce que nous avons accompli jusqu'à présent et ce qui nous attend.
Les chapitres 5 à 7 sont uniques dans la mesure où ils traitent chacun exclusivement de l'un des trois langages : Go, JavaScript et Python, respectivement.
La figure P-2 présente un organigramme décrivant la mise en page de ce livre et les différentes façons de le suivre.
Voici quelques "parcours de lecture" pour suivre au mieux ce livre.
Suis le livre une langue à la fois
Je te recommande ce parcours si une ou plusieurs de ces conditions s'appliquent à toi :
-
J'ai très envie de me plonger dans l'une de ces langues avant de m'attaquer aux deux autres.
-
Je suis particulièrement curieux (ou sceptique !) de savoir comment fonctionne le TDD dans l'une des trois langues.
-
J'apprends mieux en travaillant dans une langue à la fois, plutôt que dans plusieurs langues simultanément.
Suis l'organigramme présenté à la figure P-2, une ligne à la fois. Par exemple, si tu es désireux d'apprendre d'abord le TDD en Go, saute les sections marquées JavaScript et Python lors de la première lecture. Fais ensuite un deuxième passage dans le livre pour JavaScript, et un troisième pour terminer en Python. Tu peux aussi faire les langues dans un ordre différent. La deuxième et la troisième lecture devraient être plus rapides que la première ; cependant, prépare-toi aux bizarreries uniques de chaque langage !
Si tu suis le livre de cette façon, tu verras que le fait d'écrire le code successivement dans chaque langue te permet de mieux comprendre le TDD en tant que principe - au-delà desdétails des tests en tant que caractéristique de la langue. Prendre l'habitude d'écrire des tests est nécessaire ; cependant, comprendre les raisons pour lesquelles le développement piloté par les tests fonctionne dans tous les langages est encore plus important.
Suis le livre dans deux langues d'abord, puis dans la troisième langue.
Je te recommande ce parcours si tu te reconnais dans l'une des affirmations suivantes :
-
Je veux construire et comparer les solutions au même problème dans deux langues.
-
Je suis moins à l'aise avec l'une des langues et je veux l'aborder après les deux autres.
-
Je peux coder dans deux langues à la fois, mais j'aurais du mal à jongler avec les trois à la fois.
Suis l'organigramme de la figure P-2, deux lignes à la fois. Lorsque tu as fini de suivre le problème de l'argent pour deux langues, fais un deuxième passage dans le livre pour suivre la troisième langue.
Il peut arriver que tu veuilles suivre deux langues au premier passage, mais que tu ne puisses pas décider quelle langue reporter à une deuxième lecture. Voici quelques suggestions pour choisir deux langues parmi les trois :
-
Veux-tu opposer un langage à typage dynamique à un langage à typage statique et garder la pile technologique du langage simple ? Suis d'abord Go et Python, puis JavaScript.
-
Es-tu prêt à apprendre des façons contrastées de construire du code dans deux langages différents et prêt à t'attaquer aux variations de la pile technologique ? Suis d'abord Go et JavaScript, puis Python plus tard.
-
Veux-tu comparer et opposer deux langages à typage dynamique ? Suis d'abord JavaScript et Python, puis Go.
Si tu lis le livre de cette façon, tu découvriras rapidement les similitudes et les différences de la méthode TDD dans plusieurs langages. Bien que les variations syntaxiques et de conception des langages créent des différences évidentes, tu seras peut-être surpris de voir à quel point la discipline du TDD s'infiltre dans ta façon d' écrire du code, quel que soit le langage dans lequel tu écris du code.
Suis le livre dans les trois langues simultanément
Je te recommande ce parcours si l'une de ces affirmations s'applique à toi :
-
Tu veux en tirer le meilleur parti en apprenant les contrastes et les similitudes des trois langues.
-
Tu trouves plus facile de lire un livre du début à la fin au lieu de le parcourir plusieurs fois.
-
Tu as une certaine expérience dans les trois langues mais tu n'as pratiqué le TDD dans aucune d'entre elles.
Si tu peux écrire du code dans trois langues simultanément sans te laisser déborder, je te recommande cette voie.
Quelle que soit la voie que tu choisis, garde à l'esprit que lorsque tu écriras du code, tu seras probablement confronté à des défis liés à ton environnement de développement spécifique. Bien que le code de ce livre ait été testé pour sa correction (et que son build d'intégration continue soit vert), cela ne signifie pas qu'il fonctionnera sur ton ordinateur du premier coup. (Au contraire, je peux presque garantir que tu trouveras des portions intéressantes et abruptes sur la courbe d'apprentissage). L'un des principaux avantages du TDD est que tu contrôles la vitesse à laquelle tu procèdes. Lorsque tu es bloqué, ralentis. Si tu progresses par petits incréments, il est plus facile de trouver où le code s'est égaré. Écrire un logiciel, c'est faire face à des dépendances errantes, à des connexions réseau peu fiables, à des outils excentriques et aux mille chocs naturels dont le code est l'héritier. Ralentis quand tu te sens dépassé : fais des changements plus petits et discrets. Rappelle-toi : TDD est un moyen de gérer la peur d'écrire du code !
Conventions utilisées dans ce livre
Deux catégories de conventions utilisées dans ce livre nécessitent une explication : les conventions typographiques et les conventions contextuelles.
Conventions typographiques
La prose de ce livre est dans le type de police utilisé dans cette phrase. Elle est destinée à être lue et non à être saisie mot pour mot en tant que code. Lorsque des mots utilisés dans la prose sont également utilisés dans le code - tels que class
, interface
, ou Exception
- une police à largeur fixe est utilisée. Cela te signale que le terme est ou sera utilisé - orthographié exactement de la même façon - dans le code.
Les segments de code plus longs sont séparés dans leurs propres blocs, comme indiqué ci-dessous.
package
main
import
"fmt"
...
func
main
(
)
{
fmt
.
Println
(
"hello world"
)
}
Tout ce qui se trouve dans un bloc de code est soit quelque chose que tu saisis mot pour mot , soit quelque chose que le programme produit comme sortie littérale, à deux exceptions près.
-
Dans les blocs de code, les ellipses (
...
) sont utilisées pour indiquer soit le code omis, soit la sortie omise. Dans les deux cas, ce qui est omis n'a rien à voir avec le sujet en cours. Tu ne dois pas taper ces ellipses dans le code ou t'attendre à les voir dans la sortie. Un exemple est donné dans le bloc de code ci-dessus. -
Dans les blocs de code qui affichent des résultats, il peut y avoir des valeurs éphémères -adresses mémoire, horodatages, temps écoulé, numéros de ligne, noms de fichiers autogénérés, etc.Lorsque tu lis ce type de sortie, tu peux ignorer les valeurs éphémères spécifiques, telles que les adresses mémoire dans le bloc suivant :
AssertionError
:
<
money
.
Money
object
at
0x10417b2e0
>
!=
<
money
.
Money
object
at
0x10417b400
>
Astuce
Les astuces sont des suggestions qui peuvent t'être utiles pendant que tu écris du code. Ils sont séparés du texte principal pour pouvoir s'y référer facilement.
Important
Les informations importantes qui sont vitales pour le sujet sont identifiées de cette façon. Il y a souvent des liens hypertextes ou des notes de bas de page vers des ressources qui fournissent plus d'informations sur le sujet.
Dans la plupart des chapitres, le code de chacun des trois langages est développé et discuté. (Les exceptions sont les chapitres 5, 6 et 7, qui traitent exclusivement de Go, JavaScript et Python respectivement). Pour séparer la discussion de chaque langage, un titre et une icône dans la marge indiquent le langage qui est du ressort exclusif de cette section. Garde l'œil ouvert pour repérer ces trois titres et icônes :
-
Go
-
JavaScript
-
Python
Conventions lexicales
Ce livre aborde les concepts fondamentaux des logiciels et étaye ces discussions par du code dans trois langages différents. Les langages sont suffisamment différents dans leur terminologie individuelle pour présenter des défis lors de la discussion de concepts communs.
Par exemple, Go n'a pas de classes ni d'héritage basé sur les classes. Le système de type de JavaScript a des objets basés sur des prototypes - ce qui signifie que tout est vraiment un objet, y compris les choses typiquement considérées comme des classes. Python, tel qu'il est utilisé dans ce livre, a des objets plus "traditionnels" basés sur des classes.2 Une phrase comme "Nous allons créer une nouvelle classe nommée Money
" n'est pas seulement déroutante, elle est carrément incorrecte lorsqu'elle est interprétée dans le contexte de Go.
Pour réduire les risques de confusion, j'ai adopté la terminologie générale du tableau P-1 pour désigner les concepts clés.
Durée | Signification | Équivalent en Go | Équivalent en JavaScript | Équivalent en Python |
---|---|---|---|---|
Entité |
Un concept de domaine singulier, ayant une signification indépendante ; un nom clé. |
Type de structure |
Classe |
Classe |
Objet |
Une instance d'une entité ; un nom réifié. |
Instance de structure |
Objet |
Objet |
Séquence |
Une liste séquentielle d'objets de longueur dynamique |
Tranche |
Array |
Array |
Hashmap |
Un ensemble de paires (clé-valeur), où les clés et les valeurs peuvent être des objets arbitraires et où aucune clé ne peut être la même. |
Carte |
Carte |
Dictionnaire |
Fonction |
Un ensemble d'opérations avec un nom donné ; les fonctions peuvent (ou non) avoir des entités avec des entrées et des sorties, mais elles ne sont pas associées directement à une entité. |
Fonction |
Fonction |
Fonction |
Méthode |
Une fonction associée à une entité. On dit qu'une méthode est "appelée" sur une instance de cette entité (c'est-à-dire un objet). |
Méthode |
Méthode |
Méthode |
Signale une erreur |
Mécanisme par lequel une fonction ou une méthode indique un échec. |
Valeur de retour d'erreur (conventionnellement, la dernière valeur de retour d'une fonction/méthode). |
Lance une exception |
Lève une exception |
L'objectif est d'utiliser des termes qui expliquent les concepts sans favoriser la terminologie d'un langage de programmation par rapport à d'autres. Après tout, ce qu'il faut retenir de ce livre, c'est que le développement piloté par les tests est une discipline qui peut être pratiquée dans n'importe quel langage de programmation.
Dans les sections du livre qui traitent de l'un des trois langages (qui sont clairement indiquées dans le titre), le texte utilise des termes spécifiques au langage. Par exemple, dans une section sur Go, il y aura des instructions pour "définir une nouvelle structure nommée Money
." Le contexte indique clairement que cette instruction est spécifique à un langage particulier.
Utiliser des exemples de code
Le code source de ce livre est disponible à l'adresse https://github.com/saleem/tdd-book-code.
Si tu as une question technique ou un problème pour utiliser les exemples de code, envoie un courriel à bookquestions@oreilly.com.
Ce livre est là pour t'aider à apprendre et à pratiquer l'art du développement piloté par les tests. En général, tu peux utiliser tout le code fourni dans ce livre dans tes programmes et ta documentation. Tu n'as pas besoin de nous contacter pour obtenir une autorisation, sauf si tu reproduis une partie importante du code. Par exemple, l'écriture d'un programme qui utilise plusieurs morceaux de code de ce livre ne nécessite pas d'autorisation. La vente ou la distribution d'exemples tirés des livres d'O'Reilly nécessite une autorisation. Répondre à une question en citant ce livre et en citant un exemple de code ne nécessite pas d'autorisation. Incorporer une quantité importante d'exemples de code de ce livre dans la documentation de ton produit nécessite une autorisation.
Nous apprécions l'attribution, mais nous ne l'exigeons généralement pas. Une attribution comprend généralement le titre, l'auteur, l'éditeur et l'ISBN. Par exemple : "Apprendre le développement piloté par les tests par Saleem Siddiqui (O'Reilly). Copyright 2022 Saleem Siddiqui, 978-1-098-10647-8."
Si tu penses que ton utilisation des exemples de code ne relève pas de l'utilisation équitable ou de l'autorisation donnée ci-dessus, n'hésite pas à nous contacter à l'adresse permissions@oreilly.com.
Comment nous contacter
Nous avons une page web pour ce livre, où nous listons les errata, les exemples et toute information complémentaire. Tu peux accéder à cette page à l'adresse https://oreil.ly/learningTDDbook.
Envoie un courriel à bookquestions@oreilly.com pour faire des commentaires ou poser des questions techniques sur ce livre.
Pour des nouvelles et des informations sur nos livres et nos cours, visite le site http://oreilly.com.
TDD - Les raisons
Les critiques du TDD - et, par voie de conséquence, de ce livre - peuvent se présenter sous diverses formes. Certaines d'entre elles sont créativement humoristiques, comme la caricature rafraîchissante de Jim Kersey présentée à la figure P-3.
De façon moins facétieuse, il est naturel de se poser des questions sur le contenu et la structure du livre. Tu trouveras ci-après les réponses à quelques-unes de ces questions.
Pourquoi ce livre utilise-t-il Go, JavaScript et Python ?
Ce livre utilise Go, JavaScript et Python comme les trois langages avec lesquels démontrer la pratique du développement piloté par les tests. C'est une question légitime : pourquoi ces trois langages ?
Voici quelques raisons.
1. Variété
Les trois langues présentées dans ce livre représentent une diversité d'options de conception, comme le montre le tableau P-2.
Fonctionnalité | Go | JavaScript | Python |
---|---|---|---|
Orienté objet |
Oui (en tant que langage conforme à ES.next) |
Oui |
|
Types statiques et dynamiques |
Typé statique |
Typé dynamiquement |
Typé dynamiquement |
Types explicites et types implicites |
La plupart du temps explicite, les types de variables peuvent être implicites. |
Implicitement typé |
Implicitement typé |
Coercition de type automatique |
Pas de coercition de type |
Coercition partielle des types (pour les booléens, les nombres, les chaînes de caractères et les objets). Pas de coercion pour les types arbitraires |
Certaines coercitions de type implicites (par exemple, |
Mécanisme d'exception |
Par convention, le deuxième type de retour des méthodes est |
Le mot-clé |
Le mot-clé |
Génériques |
Pas nécessaire en raison du typage dynamique |
Pas nécessaire en raison du typage dynamique |
|
Soutien aux tests |
Partie du langage (c'est-à-dire le paquetage |
Ne fait pas partie du langage, de nombreuses bibliothèques sont disponibles (par exemple, Jasmine, Mocha, Jest). |
Partie du langage (c'est-à-dire la |
2. La popularité
Python, JavaScript et Go sont les trois nouveaux langages que les développeurs souhaitent le plus apprendre, comme le montrent plusieurs enquêtes annuelles menées par Stack Overflow en 2017, 2018, 2019 et 2020. La figure P-4 montre le résultat de l'enquête de 2020.
Dans l'enquête 2021 de Stack Overflow, TypeScript grimpe à la deuxième place, reléguant JavaScript et Go respectivement à la troisième et à la quatrième place. Python conserve sa première place.
D'un point de vue syntaxique, TypeScript est un surensemble strict de JavaScript. Par conséquent, on pourrait affirmer que tout développeur souhaitant apprendre TypeScript doit connaître JavaScript. Je nourris l'espoir que les développeurs TypeScript trouveront également ce livre précieux.
3. Une raison personnelle
Au cours des cinq dernières années environ, j'ai eu l'occasion de travailler sur plusieurs projets où la pile technologique comportait l'un de ces trois langages comme principal langage de programmation. En travaillant avec d'autres développeurs, j'ai constaté qu'en général, leur empressement à apprendre et à pratiquer le TDD était égal à leur incapacité à trouver les ressources (ou à rassembler la discipline) pour le faire. Ils voulaient pratiquer le TDD, mais ne savaient pas comment ou ne trouvaient pas le temps de le faire. Il est révélateur que cela soit aussi vrai pour les développeurs chevronnés que pour les "novices".
J'espère que ce livre servira à la fois de guide pratique et de source d'inspiration à ceux qui veulent apprendre et pratiquer le TDD dans n'importe quel langage - et pas seulement en Go, JavaScript ou Python.
Pourquoi pas cette autre langue ?
Tout d'abord, il existe un grand nombre de langages de programmation. Il serait concevable d'écrire une demi-douzaine de livres comme celui-ci et de ne couvrir qu'une petite fraction des langages que les développeurs du monde entier utilisent quotidiennement pour écrire du code à des fins académiques, commerciales et récréatives.3
D'ailleurs, il existe déjà un excellent livre sur le développement piloté par les tests en Java. C'est l'ouvrage fondateur de Kent Beck qui m'a incité, comme d'innombrables autres développeurs, à tomber amoureux de l'art et de la science du TDD. Il a également engendré le "problème de l'argent" qui est un thème majeur de ce livre.
Je suis sûr qu'il y a beaucoup d'autres langages pour lesquels un guide pratique de TDD serait bénéfique. Pourquoi pas R ? Ou SQL ? Ou même COBOL ?
Je te rassure : la référence à COBOL n'était ni un argument d'homme de paille ni un coup bas. Au milieu des années 2000, j'ai travaillé sur un projet dans lequel j'ai démontré la possibilité de faire du TDD en COBOL en utilisant COBOLUnit. C'est le plus grand plaisir que j'ai eu dans un langage qui a plus d'une décennie de plus que moi !
J'espère que tu reprendras le flambeau. Que tu apprendras, enseigneras et épouseras les compétences et la discipline nécessaires pour pratiquer le développement piloté par les tests dans d'autres langages. Que tu écriras un blog, un projet open source ou le prochain livre de cette série.
Pourquoi ce livre a-t-il un "chapitre 0" ?
La grande majorité des langages de programmation utilisent l'indexation basée sur 0 pour les tableaux et autres séquences dénombrables.4 C'est certainement vrai pour les trois langages de programmation qui constituent la base de ce livre. Dans un sens, ce livre rend hommage à la riche histoire de la culture de la programmation en numérotant les chapitres à partir de 0.
Je veux aussi rendre hommage au chiffre zéro lui-même, ce qui est une idée radicale. Charles Seife a écrit un livre entier sur ce nombre solitaire. En retraçant l'histoire du zéro, Seife note les réserves que les Grecs avaient à l'égard d'un nombre qui ne représente rien:
Dans cet univers [c'est-à-dire l'univers grec], le néant n'existe pas. Le zéro n'existe pas. Pour cette raison, l'Occident n'a pas pu accepter le zéro pendant près de deux millénaires. Les conséquences étaient désastreuses. L'absence de zéro allait freiner l'essor des mathématiques, étouffer l'innovation dans les sciences et, accessoirement, mettre le bazar dans le calendrier. Avant d'accepter le zéro, les philosophes occidentaux devaient détruire leur univers.
Charles Seife, Zéro : la biographie d'une idée dangereuse
Au risque de devenir trop sublime : le développement piloté par les tests occupe aujourd'hui dans la culture de la programmation une place similaire à celle qu'occupait le zéro dans la philosophie occidentale il y a quelques millénaires. Il y a une résistance à l'adopter, née d'une étrange combinaison de rejet, de malaise et de croyance qu'il s'agit simplement de trop d'agitation pour rien. "Pourquoi devrais-je être fastidieux en écrivant d'abord des tests - je sais déjà comment je vais coder la fonctionnalité !". "Le développement piloté par les tests est pédant : il ne fonctionne qu'en théorie et jamais en pratique." "Écrire des tests après avoir fini d'écrire le code de production est au moins aussi efficace, sinon plus, que d'écrire des tests en premier." Ces objections et d'autres encore font ressembler le TDD au chiffre zéro par sa radicalité !
La pratique d'un livre ayant un chapitre 0 n'est pas tout à fait radicale, de toute façon. Carol Schumacher a écrit un livre entier intitulé Chapter Zero : Fundamental Notions of Abstract Mathematics (Notions fondamentales des mathématiques abstraites), qui est un manuel standard pour les mathématiques avancées dans de nombreux programmes d'enseignement supérieur. Il n'y a pas de prix pour deviner par quel chapitre numéroté commence ce livre !
Le Dr Schumacher, dans le manuel de l'instructeur de son livre, dit quelque chose que j'ai trouvé éclairant :
Ta tâche en tant qu'écrivain est de donner les bons indices à tes lecteurs, des indices qui leur permettront de comprendre aussi facilement que possible ce que tu essaies de dire.
Carol Schumacher, Manuel de l'instructeur à utiliser avec le chapitre zéro
J'ai pris ce conseil à cœur. De manière pragmatique, un titre contenant "0" permet de distinguer le chapitre 0 du traité qui le suit. Le chapitre 1 de ce livre nous met sur la voie du TDD, qui se poursuit tout au long de la douzaine de chapitres suivants. Le chapitre 0 décrit ce qu'est ce voyage, ce que nous devons savoir et avoir avant de nous y engager, et ce à quoi nous devons nous attendre une fois sur place.
Ces précisions étant faites, passons directement au chapitre 0 !
1 Cette définition de la simplicité est inscrite dans l'un des 12 principes du Manifeste Agile.
2 Python est très fluide dans sa prise en charge de la programmation orientée objet (POO). Par exemple, voir prototype.py
, qui met en œuvre des objets basés sur des prototypes en Python.
3 Même si un livre sur le TDD sur un certain langage a peu de chances d'obtenir l'approbation des éditeurs. Son nom commence par "Brain" et se termine par un juron !
4 Lua est une exception notable. Mon ami Kent Spillner a un jour donné une conférence fascinante sur ce sujet, que j'ai résumée ici.
Get Apprendre le développement piloté par les tests now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.