Récemment, une personne ici a posé une question de base sur la façon de calculer dans Python toutes les permutations d'éléments d'une liste. Comme pour la plupart des questions posées par les étudiants, je n'ai pas fourni le code source réel dans ma réponse, mais a plutôt expliqué comment aborder le problème, qui a essentiellement abouti à une présentation de base du développement piloté par les tests.
En pensant au problème lui-même, je me suis souvenu de tous les problèmes similaires que j'avais à résoudre lorsque j'étais moi-même étudiant en programmation à l'université. On ne nous a jamais enseigné le développement piloté par les tests, ni aucune méthode comparable, mais on nous a néanmoins constamment demandé d'écrire des algorithmes qui trient des éléments d'une liste, ou résolvent des casse-têtes des tours de Hanoi, etc. savoir comment le TDD (Test Driven Development) les aiderait à résoudre les problèmes qui leur sont posés: s'ils l'étaient, ils auraient formulé leurs questions très différemment.
Le fait est que, sans TDD, tous ces problèmes sont en effet assez difficiles. Je me considère comme un développeur professionnel, mais je passerais encore un peu de temps à écrire un algorithme de classement de liste sans TDD, si on me le demandait, et je serais surtout ignorant si on me demandait de calculer toutes les permutations des éléments d'une liste, toujours sans en utilisant TDD. Avec TDD, en revanche, j'ai résolu le problème des permutations en quelques minutes en écrivant la réponse à l'élève.
Quelle est la raison pour laquelle le TDD n'est pas enseigné du tout ou du moins très tard dans les universités? En d'autres termes, serait-il problématique d'expliquer l'approche TDD avant de demander aux élèves d'écrire des algorithmes de tri de liste et des choses similaires?
Suite aux remarques de deux des questions:
Dans votre question, vous semblez présenter TDD comme un "dispositif de résolution de problèmes" [...] Dans le passé, TDD a été présenté comme un "mécanisme de découverte de solutions", mais même Bob Martin (le principal défenseur de TDD) admet que vous devez apporter une quantité importante de connaissances préalables à la technique.
et particulièrement:
Je suis curieux de savoir pourquoi vous pensez que TDD facilite un problème d'algorithme délicat avec une spécification bien définie.
Je trouve nécessaire d'expliquer un peu plus ce qui est, à mon avis, si magique à propos de TDD quand il s'agit de résoudre des problèmes.
Au lycée et à l'université, je n'avais pas de techniques spécifiques pour résoudre les problèmes, et cela s'appliquait à la fois à la programmation et aux mathématiques. Rétrospectivement, je suppose qu'une de ces techniques est de revoir la leçon/leçon actuelle/dernière et de chercher la relation avec l'exercice. Si la leçon porte sur les intégrales, il est probable que le problème que l'enseignant a demandé de résoudre nécessite l'utilisation d'intégrales. Si la conférence portait sur la récursivité, il y a des chances que le casse-tête donné aux étudiants puisse être résolu en utilisant la récursivité. Je suis également sûr qu'il existe des approches bien formalisées pour résoudre les problèmes en mathématiques, et ces approches peuvent également être appliquées à la programmation; cependant, je n'en ai jamais appris.
Cela signifie que dans la pratique, mon approche consistait simplement à faire le tour du problème en essayant de deviner comment le résoudre. À l'époque, si on me donnait le défi de générer des permutations d'éléments à partir d'une liste, je ne commencerais pas avec une liste vide en entrée, mais plutôt un exemple illustratif, tel que [4, 9, 2]
, essayant de comprendre pourquoi il y a six permutations possibles et comment les générer via du code. À partir de là, j'ai besoin de beaucoup de réflexion pour trouver un moyen possible de résoudre le problème. C'est essentiellement ce qu'a fait l'auteur de la question d'origine , en finissant par utiliser random
. De même, lorsque j'étais étudiant, aucun autre étudiant de mon âge ne commencerait par []
: tous se précipiteraient immédiatement sur le cas avec deux ou trois éléments, puis resteraient bloqués pendant une demi-heure, se retrouvant parfois avec du code qui ne compile pas ou ne s'exécute pas.
L'approche TDD, pour moi, semble contre-intuitive. Je veux dire, cela fonctionne très bien, mais je ne me serais jamais imaginé, avant de lire quelques articles sur TDD, que (1) je devrais commencer par le cas le plus simple, (2) écrire le test avant d'écrire du code, et (3 ) Never Rush, essayant de réaliser plusieurs scénarios dans le code. En regardant comment les programmeurs débutants pensent, j'ai l'impression que je ne suis pas le seul à le trouver contre-intuitif. Cela peut être, je crois, plus intuitif pour les programmeurs qui ont une bonne compréhension d'un langage fonctionnel. Je suppose que dans Haskell, par exemple, il serait naturel de gérer le problème des permutations en considérant d'abord un cas d'une liste vide, puis un cas d'une liste avec un élément, puis un cas d'une liste de plusieurs éléments. Dans les langages où des algorithmes récursifs sont possibles, mais pas aussi naturels que dans Haskell, une telle approche est cependant beaucoup moins naturelle, à moins, bien sûr, que l'on pratique le TDD.
Je suis professeur de programmation à temps partiel dans un collège communautaire local.
Le premier cours enseigné dans ce collège est Programmation et algorithmes Java. Il s'agit d'un cours qui commence par des boucles et des conditions de base, et se termine par l'héritage, le polymorphisme et une introduction aux collections. Tout en un semestre, pour les étudiants qui n'ont jamais écrit une ligne de code auparavant, une activité qui est complètement exotique pour la plupart d'entre eux.
J'ai été invité une fois à un comité de révision des programmes d'études. Le conseil a identifié un certain nombre de problèmes avec le programme CS du collège:
Mon conseil pour eux? Ajoutez une classe de synthèse de deux semestres au programme d'études où les étudiants peuvent écrire une application complète, un cours qui couvrirait l'ensemble du cycle de vie du développement logiciel, de la collecte des exigences au déploiement. Cela permettrait de les embaucher chez des employeurs locaux (au niveau des apprentis).
Alors, où TDD s'intègre-t-il dans tout cela? Honnêtement, je ne sais pas.
Dans votre question, vous semblez présenter TDD comme un "dispositif de résolution de problèmes"; Je vois TDD principalement comme un moyen d'améliorer la conception et la testabilité du code. Dans le passé, le TDD a été présenté comme un "mécanisme de découverte de solutions", mais même Bob Martin (le principal défenseur du TDD) admet que vous devez apporter une quantité importante de connaissances préalables à la technique.
En d'autres termes, vous devez toujours savoir comment résoudre les problèmes de code en premier. TDD vous pousse juste dans la bonne direction générale par rapport aux spécificités de la conception logicielle. Cela en fait un cours de niveau supérieur, pas un cours de niveau inférieur.
Tout d'abord, nous devons fondamentalement distinguer entre Informatique et Génie logiciel . (Et peut-être dans une moindre mesure entre le génie logiciel et la programmation ou le "codage".)
Comme l'a dit un de mes professeurs CS: si vous avez besoin d'un clavier, vous ne faites pas de CS.
TDD est une pratique de génie logiciel. Cela n'a pas vraiment de rapport avec l'informatique. Donc, si vous demandez pourquoi les étudiants CS n'apprennent pas le TDD, c'est parce que le TDD n'a pas vraiment grand-chose à voir avec le CS.
Maintenant, l'ingénierie logicielle, c'est une toute autre marmite de poisson. Je suis tout à fait d'accord pour dire que TDD devrait y être enseigné. J'ai eu un cours de génie logiciel (90 minutes par semaine pendant un semestre) et dans cette classe, nous avons appris Waterfall, V-Model, RUP, CMM, CASE , RAD, Spiral, Iterative, et probablement quelques autres trucs que j'ai oubliés. Il y aurait sûrement eu de la place pour intégrer le TDD, surtout si vous l'intégriez au reste des cours et appliquiez le TDD à tous les devoirs et travaux en classe dans tous les cours où la programmation est requise.
Pour être juste, cependant, dans mon cas, le Manifeste Agile n'avait pas encore été écrit, et TDD était une technique de niche obscure.
Si vous jetez un oeil à mon préféré pour l'enseignement de la programmation, Comment concevoir des programmes , vous constaterez qu'ils enseignent très dès le début que les fonctions devraient venir avec des exemples d'utilisation et seulement un peu plus tard, le livre présente les tests unitaires automatisés et suggère que ces exemples d'utilisation soient écrits sous forme de tests. Ils enseignent également que les exemples d'utilisation et ce qu'ils appellent des "déclarations de but" (vous pouvez le considérer comme la ligne de résumé d'un commentaire JavaDoc) doivent être écrits avant le code.
Ils n'enseignent pas explicitement le TDD (ils ont leur propre méthodologie), mais c'est au moins un peu proche. HtDP est conçu pour que les élèves du secondaire reçoivent un enseignement en moins d'un an, donc je pense qu'il est plus que possible de l'enseigner en un seul semestre à l'université.
Pour être honnête, cependant, ce serait déjà une grande victoire que les étudiants apprennent simplement qu'ils peuvent réellement exécuter le code qu'ils ont écrit avec différentes entrées. (En d'autres termes, une forme grossière de test manuel.) Je suis étonné de voir combien de fois les étudiants ne sont pas en mesure de franchir cette étape mentale.
Par exemple, j'ai vu plusieurs questions sur Stack Overflow qui équivalent à "quelle méthode dois-je implémenter pour faire fonctionner ce code". Notez qu'il ne s'agissait pas du code de la méthode (le demandeur savait comment implémenter la méthode), il s'agissait purement du nom . Cependant, aucun des demandeurs n'a eu l'idée de simplement exécuter le code et de regarder le nom de la méthode manquante dans le NoMethodError
exception qui sera invariablement levée.
TDD est un processus agréable dans la programmation "du monde réel" car les problèmes arrivent souvent sur nos bureaux sous-spécifiés. "Ajouter une fonctionnalité qui fait X", "corrige le bogue où il montre la mauvaise chose si vous faites Y", etc. TDD nous oblige à créer une spécification avant de commencer la programmation.
Dans les classes CS/programmation, les problèmes nous arrivent généralement extrêmement bien spécifiés. Msgstr "Écrire une fonction qui prend un tableau de nombres entiers et retourne un tableau avec les mêmes nombres entiers disposés en ordre non décroissant". La spécification nous est remise.
Je suis curieux de savoir pourquoi vous pensez que TDD facilite un problème d'algorithme délicat avec une spécification bien définie. Plus précisément, je veux que vous expliquiez ceci:
Je serais surtout désemparé si on me demandait de calculer toutes les permutations des éléments dans une liste, toujours sans utiliser TDD. Avec TDD, en revanche, j'ai résolu le problème des permutations en quelques minutes en écrivant la réponse à l'élève.
Je suppose que vous le direz parce que vous avez écrit des cas de test qui affirmaient P([]) -> [[]]
, P([1]) -> [[1]]
, P([1, 2]) -> [[1, 2], [2, 1]]
, etc., et qui vous ont fait voir comment la récursivité devait fonctionner . Mais ce n'est pas TDD, c'est juste ... penser au problème. Vous pouvez penser au problème sans écrire des tests unitaires réels qui échouent.
Je suppose que c'est principalement parce que l'écriture de tests automatisés est plus difficile que l'écriture du code testé. Lorsque vous rencontrez toujours des difficultés avec les mécanismes de base, il est difficile d'ajouter un autre calque. En outre, comme d'autres réponses l'ont souligné, le TDD est perçu comme un processus de génie logiciel, même si ses praticiens le considèrent davantage comme un dispositif didactique. De plus, savoir quels tests écrire en premier est une compétence en soi.
Si j'enseignais un cours d'introduction, je fournirais quelques tests dans l'ordre TDD et demandais aux étudiants de réussir les tests un par un dans cet ordre. C'est une expérience très similaire de jumeler la programmation avec un mentor expérimenté. Personnellement, je pense que cela rendrait les cours comme les algorithmes plus faciles à enseigner, ce qui compenserait le temps consacré à la technique, en raison de la progression pas à pas. Cela amènerait les étudiants à réfléchir à des questions telles que: "J'ai du code de travail éprouvé qui trouvera toutes les permutations d'une liste à deux éléments. Comment puis-je réutiliser autant de code que possible pour le faire fonctionner pour 3 éléments ou plus?
Le problème de base est que inventer les tests dans le processus TDD n'a rien à voir avec l'informatique ou le génie logiciel. Il nécessite une connaissance du domaine d'application.
Bien sûr, c'est la force du TDD dans les applications du monde réel: vous ne pouvez pas vous empêcher de penser à quoi le système que vous construisez va réellement être utilisé. Mais dans les activités typiques de CS et SE, les tâches confiées à l'élève ont un contexte minimal et n'existent que pour tester ou illustrer un objectif d'apprentissage.
Par exemple, si l'objectif d'apprentissage est de démontrer la compréhension de la construction "case" dans un langage de programmation, TDD n'est pas pertinent: vous pouvez écrire un logiciel qui réussit tous les tests TDD sans utiliser "case" du tout. Si l'exemple était artificiel, ne pas utiliser "cas" pourrait en fait être une meilleure solution au problème dans le monde réel, mais pas en termes d'objectif d'apprentissage qui était prévu.
Encourager les étudiants à inventer leurs propres cas de test et à les exécuter, mais essayer d'utiliser un processus TDD formel n'est pas la question.
Un deuxième problème est peut-être davantage lié à la façon dont le CE et le SE sont enseignés, mais il est toujours pratique: comment noter le niveau de l'élève collection de tests lors de l'utilisation du TDD? Il n'y a aucun moyen évident d'automatiser ce processus.
Même si vous produisez une solution modèle qui dit "vous devriez avoir testé pour les 15 ou 20 situations suivantes", vous devez toujours identifier manuellement lequel des tests de l'élève correspond (en tout ou en partie) à chaque partie de la réponse de votre modèle. Et sauf dans des cas triviaux, l'étudiant peut avoir produit un bon ensemble de tests qui sont logiquement structurés d'une manière différente de la réponse du modèle.
L'élève moyen a vraiment une mauvaise vue d'ensemble de ce qu'il est censé savoir et faire. Pour enseigner le TDD, ils devraient comprendre:
Comment résoudre les problèmes techniques. Au début, ils pensent que le code est écrit en une seule fois. Ce n'est que plus tard lorsqu'ils réalisent des stratégies de débogage de base qu'ils passent à une écriture plus incrémentielle. Même si vous leur dites cela d'avance, ils le feront toujours de cette façon parce qu'ils pensent que c'est ainsi que les choses se font (c'est d'ailleurs aussi pourquoi les gens ne savent pas dessiner, jouer du piano, faire des mathématiques, etc., etc.). )
Comment introspecter vos propres actions pour trouver des schémas reproductibles dans votre propre comportement. Une fois que vous pouvez le faire, vous pouvez automatiser votre propre travail. Mais cela est totalement étranger à la plupart des gens jusqu'à ce qu'ils atteignent un certain niveau.
Comment rédiger les exigences.
Comprendre les cas d'angle de votre espace problématique.
Comprendre la philosophie d'ingénierie sur la gestion des risques. (ha mais vous ne savez même pas que vous êtes un bon ingénieur)
Comprendre la refactorisation et la maintenance du code.
Comprendre le fonctionnement de la programmation dans une vraie entreprise.
En fait, j'ai eu des collègues qui ont été initiés au TDD trop tôt, ils n'en ont pas vraiment profité. Cependant, il est toujours possible de faire des pas de bébé vers cet effet. C'est juste que les gens ont besoin d'une certaine expérience derrière eux pour en bénéficier.
Vous pouvez donc l'enseigner, mais pas quelque chose avec lequel vous commencez. D'autant plus qu'il existe du code qui ne se prête pas très facilement à TDD.
Le TDD n'est pas plus populaire dans les universités, car (généralement) les universités font un très mauvais travail en assurant que les connaissances qui sont données aux étudiants peuvent être transposées dans des contextes réels.
On peut dire que ce n'est pas le rôle de l'université en premier lieu et qu'il s'agit davantage d'enseigner les principes fondamentaux et les concepts de base de la CS. C'est instructif, important et, essentiel, si les étudiants sont intéressés à poursuivre une carrière dans le monde universitaire, mais cela ne suffit pas lorsque les étudiants termineront leurs diplômes et s'inscriront dans l'industrie, en travaillant intégrés dans une équipe, qui suit le développement meilleures pratiques, CI/CD, etc.
De toute évidence, il y a des intersections et les deux peuvent bénéficier l'un de l'autre, mais, en fin de compte, l'université n'est tout simplement pas encore au courant de ce qui doit être fait pour obtenir un diplôme d'ingénieurs en logiciels plus compétents, pertinents et à jour.
Pour répondre directement à la question:
Comme quelqu'un l'a suggéré, il y a suffisamment d'apprentissage pour un semestre entier. Un cours séparé? Peut être. Je pouvais voir TDD combiné avec des sujets de conception de logiciels. La plus grande valeur de l'OMI TDD est de verrouiller les comportements existants afin que nous puissions ajouter de nouveaux comportements plus tard, et changer la conception pour les adapter à ces nouveaux comportements. Donc une classe de conception de logiciels?
Ce serait bien de voir le processus de réflexion derrière TDD (mal nommé, et j'ai demandé à Kent Beck s'il reconsidérer; il a dit "que le train a quitté la gare") être introduit le plus tôt possible. J'utilise du code depuis 1976 et je sais que TDD ne semblait pas très naturel au début. Mais maintenant, c'est assez naturel. Mon temps n'est pas récupéré en écrivant du code de test, il est récupéré plus tard, quand je n'ai à réparer un défaut grave qu'une fois par an ).
J'encourage les nouveaux diplômés à l'essayer pendant un mois. Mais ce serait tellement plus facile pour eux s'ils étaient exposés au TDD beaucoup plus tôt. Je trouve utile d'utiliser le framework de test unitaire lorsque j'apprends un nouveau langage (Histoire vraie: "Maintenant, comment puis-je faire passer ce test en Ruby? PEUT-ÊTRE que cela fonctionnera ... HEY IT WORKED!"), Ou explorer une nouvelle bibliothèque ("Les documents sont vagues sur l'ordre de ceux-ci seront retournés ... je vais écrire un test ...").
Je trouve que TDD est utile lors de la mise en œuvre d'un algorithme (sans en inventer un ... j'y arriverai), ou lors de la création d'une règle commerciale légèrement compliquée à partir de zéro, pour ainsi dire. Chaque test qui passe est "verrouillé" pour l'éternité. Si le test est suffisamment discret, il ne devra jamais changer (mais ça prend beaucoup plus d'un mois pour être bon).
Il serait donc intéressant d'intégrer TDD dans les classes de programmation antérieures. Trois points d'amélioration:
Une autre chose qui pourrait être utile est un manuel ou, à tout le moins, un programme condensé de no-nonsense avec des laboratoires conçus pour transmettre divers aspects de la pratique TDD. J'ai une suggestion pour cela (voir expérience/clause de non-responsabilité plus tard).
Pour répondre aux critiques:
Je suis nouveau ici, mais je note que certaines "réponses" ne répondent pas à la question, mais sont de bonnes critiques du TDD. Je suppose donc qu'il est normal de répondre à certaines de ces préoccupations?
Si les développeurs travaillant sur un produit pendant plus de quelques mois passaient vraiment la majorité de leur temps à écrire de nouvelles fonctionnalités, alors ce serait négatif. Mais les six équipes TDD sur lesquelles j'ai travaillé en tant que développeur ont passé leur temps de cette façon, alors que la décennie que j'ai passée à utiliser le code avant TDD a été principalement consacrée au débogueur, ou à copier/coller/modifier avec précaution afin de ne pas casser plus vieux/le code de quelqu'un d'autre. Les avantages de TDD ne sont pas tous instantanés, mais ils ont été remarquablement fiables et incroyablement précieux, mesurés par la réduction des heures supplémentaires (et du stress) des développeurs et augmentation des revenus = . Conclusion: j'ai toujours eu hâte de travailler avec ces équipes TDD. (Une fois que j'avais bu du thé.)
Lorsque vous écrivez un "test" (alias spécification, alias scénario), vous devez connaître la réponse! De plus, vous voulez écrire un test qui est une petite bouchée de la solution que vous avez déjà une idée (connaissance préalable) de la façon dont vous allez l'implémenter.
Ce qui est souvent une surprise, c'est la clarté et la simplicité de la conception si nous prêtons attention aux odeurs de code et si nous refactorisons au besoin chaque fois que tous les tests liés à ce code passent.
Personne ne suggère de jeter notre bonne connaissance des modèles de conception ou des idiomes de langage, ou des principes SOLID, ou comment jouer au Sudoku, ou comment écrire un tri par tas).
TDD consiste à créer un filet de sécurité qui nous donne la confiance nécessaire pour ajouter rapidement de nouvelles fonctionnalités et modifier la conception pour s'adapter à ces nouvelles fonctionnalités sans rien casser d'autre.
UTA est en train de rapiécer le filet de sécurité après que quelqu'un soit tombé dans un trou jusqu'à sa mort. (Note latérale intéressante: Le projet OTIS2 est un système vital, donc le risque de mort des patients n'était pas une blague pour nous. Plus de 20 000 tests tous exécutés en 10 minutes, maintenant qui est un safetynet!)
Expérience/dénis de responsabilité:
J'ai fait du TDD à plein temps de 1998 à 2004 et avec environ 6 équipes différentes. Tous étaient au moins 6 mois de développement. Avant cela, j'avais passé 13 ans à écrire des logiciels dans l'autre sens, et je suis venu à détester les débogueurs et les tests manuels avec printf ().
J'ai commencé à enseigner les pratiques de développement de logiciels en 2001, y compris maintenant les cours TDD, BDD et SA-CSD. Bien sûr, c'est une bonne vie, mais je sais aussi que TDD est un moyen simple de rendre le développement de logiciels centré sur l'équipe sain et agréable à nouveau. Donc...
J'écris ce que j'espère devenir un manuel collégial ou secondaire (avec des dépôts en ligne, des laboratoires, des vidéos, etc., bien sûr): Essential Test-Driven Development
Je n'ai jamais considéré le TDD comme un moyen de résoudre un problème et après avoir lu votre question, je ne le fais toujours pas.
TDD vous oblige simplement à regarder un problème d'un côté: celui du client. Cela peut vous empêcher de trouver une solution qui ne correspond pas à la question du client. C'est généralement une bonne chose, bien que cela puisse également vous limiter, cela vous empêche de regarder le problème sous un angle plus large, il peut y avoir une meilleure solution, plus générale, au problème que votre client n'a pas considéré.
Une autre façon de voir les choses est qu'il s'agit de l'approche descendante ultime. TDD pourrait représenter Top Down Development. Vous commencez le développement au niveau le plus élevé et zoomez progressivement.
De toute façon, c'est un concept abstrait. Vous pouvez en parler à un élève, fournir une définition, mais ce sera tout. Vous ne pouvez pas poser autant de questions à ce sujet lors d'un examen. Donc, dans n'importe quelle classe SE ou CS, bien qu'utile dans un contexte SE, elle ne pourrait jamais être plus qu'une note annexe.
On m'a enseigné l'informatique dans les années 1970, bien avant que l'acronyme TDD ne soit inventé, et bien sûr on ne nous a jamais explicitement enseigné la technique. Mais pour l'un des exercices de programmation qui nous ont été donnés, nous avons reçu un ensemble de cas de test et on nous a dit que notre solution devait passer les tests. J'ai donc appris la valeur de l'approche sans jamais l'enseigner explicitement, et je l'ai utilisée depuis.
Bien que l'écriture de tests soit une compétence essentielle pour le développement de logiciels, les preuves scientifiques n'indiquent pas que TDD finit par produire un meilleur logiciel que le développement itératif du dernier test (ITL) (OTOH, il ne l'est pas non plus pire ).
Pour preuve, vous pouvez voir Davide Fucci et al. "Une réplication externe sur les effets du développement piloté par les tests utilisant une approche d'analyse aveugle multisite" ( link ) et la méta-analyse de Turhan et al dans Making Software ( link ).
Donc, à moins que nous commencions à voir des preuves du contraire que le TDD offre, en fait, des gains mesurables, il est moins important que le TDD en tant que pratique spécifique soit enseigné plutôt que de simplement inculquer la bonne habitude de l'écriture de test à un moment donné du processus de développement.
mais je passerais encore un peu de temps à écrire un algorithme de classement de liste sans TDD, si on me le demandait, et je serais surtout désemparé si on me demandait de calculer toutes les permutations des éléments dans une liste, toujours sans utiliser TDD. Avec TDD, en revanche, j'ai résolu le problème des permutations en quelques minutes
Cela m'embrouille sérieusement.
Pour moi, le développement piloté par les tests signifie penser tôt aux tests et prendre le temps de les implémenter et de les tenir à jour avec le code.
Bien sûr, réfléchir à ce qu'il faut tester est une bonne occasion d'élaborer le problème à résoudre et, dans certains cas, d'avoir une bonne idée des pièges.
Mais ne pas faire de TDD, ne pas se concentrer d'abord sur les tests n'empêche pas de penser au problème sous-jacent de toute façon. Vous devez toujours penser à ce que vous faites et clarifier la situation, que vous souhaitiez franchir une étape supplémentaire et implémenter des tests immédiatement ou non.
serait-il problématique d'expliquer l'approche TDD avant de demander aux élèves d'écrire des algorithmes de tri de liste et des choses similaires?
Cela dépend dans quelle mesure vous expliqueriez TDD.
Il est utile d'entendre parler de quelque chose. Mais les étudiants entendent beaucoup de choses qu'ils ne peuvent pas encore interpréter car d'autres éléments de base manquent encore. Donc, vous ne devriez pas aller trop loin dans un concept qui, sans la connaissance des bases, serait pour eux un gâchis inutile et aliénant de termes inconnus.
En plus de cela, de nombreux programmeurs savent probablement à quoi cela ressemble si vous cherchez un tutoriel sur un problème et trouvez des exemples qui montrent en effet une solution, mais vous devez d'abord trier toutes sortes d'autres choses non pertinentes l'auteur a ajouté.
Donc, pour répondre à cette question, si j'étais étudiant, j'aimerais que les choses soient séparées. Si vous annoncez pour nous expliquer comment trier une liste, veuillez nous dire comment le faire, mais ne laissez pas le chemin pour remplir les tests. Si vous voulez commencer à expliquer les tests, alors n'annoncez pas d'implémenter le tri car cela n'arrive toujours pas pendant longtemps.
Encore une fois, il faut réfléchir avant de commencer à écrire le tri ou les tests. À quoi ressemblent les listes avant et après le tri? Faites des exemples, pensez aux pièges, à ce qui doit être pris en compte pour éviter d'échouer lorsqu'une liste est vide et ainsi de suite. Tout cela doit être pris en compte mais aucune ligne de tests n'est encore écrite.
En général, je dirais que vous mélangez deux choses qui devraient être conservées séparément.
Penser au problème est très différent de se concentrer sur l'écriture de cas de test.
Une fois, je suis tombé sur un exemple de TDD par quelqu'un qui était en quelque sorte obsédé par le TDD.
Malheureusement, il m'a semblé que l'auteur aimait trop son tutoriel, donc il ne s'est pas rendu compte de ce que c'était vraiment.
L'auteur seulement s'est concentré sur les cas de test, pas sur le problème que leur code devrait gérer. Comme vous ne pouvez jamais trouver toutes les permutations d'entrée, vous devez avoir un aperçu de ce que vous faites réellement, vous devez voir l'intégralité du problème. Vous ne pouvez pas toujours commencer avec une entrée vide, puis ajouter ultérieurement une entrée supplémentaire et toujours ajouter du code pour gérer correctement la nouvelle entrée.
Vous devez avoir une idée de ce à quoi vous avez réellement affaire en général. Mais l'auteur ne l'a pas fait.
Si j'essaie de le traduire en triant une liste, nous commencerions par une liste vide, puis un élément qui peut être renvoyé tel quel, une liste avec deux éléments qui doivent peut-être être échangés et peut-être finir par une récursivité parce que trois éléments, c'est comme deux (nous l'avons déjà résolu) plus un de plus avec une étape supplémentaire ...
Un horrible szenario pour un algorithme de tri - mais personne ne le réalisera parce que nous nous concentrons uniquement sur les cas de test.
Les commentaires me font écrire un peu plus sur mon opinion.
Je pense que le terme "développement piloté par les tests" est incorrect. Il devrait s'agir de "développement supporté par les tests", ce qui signifie que nous ne nous contentons pas de coder et d'espérer, mais nous pensons également aux tests et nous savons qu'il est toujours bon de savoir tôt quand quelque chose ne va pas.
Si le développement est nommé piloté par des tests, cela pourrait impliquer que tout ne dépend que des tests et nous avons terminé dès que quelques cas de test sont satisfaits. Cette exigence serait satisfaite même par un code très insuffisant qui n'a jamais essayé de voir un problème dans son ensemble mais a été piraté d'avant en arrière jusqu'à ce que tous les cas de test deviennent accidentellement verts - puis échoue en fonctionnement réel.
Vous avez mis à jour votre question pour être plus "Pourquoi le TDD n'est-il pas enseigné comme un outil d'apprentissage de base?". D'autres réponses expliquent déjà assez bien pourquoi le TDD n'est pas un bon sujet pour le codage 101, mais la réponse principale est vraiment que le TDD, à sa base, n'est pas un outil de résolution de problèmes. Il peut être utilisé à cette fin, mais comme tout outil, vous devez d'abord comprendre quand et comment l'utiliser.
TDD est un processus de test, et donc le plus naturellement sera enseigné soit dans le cadre d'un cours de processus de développement, soit dans le cadre d'un cours de test de logiciel. En codant 101 cours, l'objectif n'est pas que les étudiants résolvent des problèmes, c'est de leur apprendre à utiliser divers concepts de programmation. En général, la plupart des projets de codage 101 et 102 seront très explicites sur la façon de résoudre le problème, les étudiants ont juste besoin de comprendre ce qu'ils ont appris pour faire la tâche d'une manière non copier-coller.
Chaque élève apprend de différentes manières. Certains élèves ont besoin de lire à ce sujet, d'autres ont besoin qu'on leur explique verbalement, et d'autres ne l'obtiendront jamais à moins qu'ils ne soient profondément au courant du code. Enseigner le TDD pour faciliter le processus d'apprentissage n'aidera pas réellement la plupart des élèves, et ceux qu'il aide? Les enseignants devront décider si le temps d'enseigner le TDD valait la vitesse d'apprentissage supplémentaire. Dans l'ensemble, l'enseignement d'une méthode d'apprentissage ne vaudra pas le temps de classe qui pourrait être consacré à des sujets spécifiques au cours. (En général, les compétences d'apprentissage et de résolution de problèmes sont généralement laissées aux élèves pour apprendre eux-mêmes, car seul l'élève peut identifier ce qui fonctionne le mieux pour eux)
TL: RD; Différentes personnes ont différents processus efficaces. Les universités ne prescrivent pas comment faire quoi que ce soit; Donnez-vous simplement les outils afin que vous puissiez faire ce qui vous convient le mieux.
TDD est un outil d'implémentation fantastique, et je pense que vous avez raison de dire qu'il est bénéfique pour ceux qui souhaitent écrire des logiciels.
Quelle est la raison pour laquelle le TDD n'est pas enseigné du tout ou du moins très tard dans les universités? En d'autres termes, serait-il problématique d'expliquer l'approche TDD avant de demander aux élèves d'écrire des algorithmes de tri de liste et d'autres choses similaires?
La principale raison est probablement que les professeurs qui enseignent ces programmes savent rarement comment développer des logiciels, car ce n'est pas leur domaine d'expertise. Comme d'autres réponses l'ont mentionné, l'informatique et le génie logiciel sont des disciplines différentes, et je comparerais l'attente que les étudiants en informatique apprennent le génie logiciel aux étudiants en physique apprenant à concevoir des voitures. Le TDD est une compétence qui nécessite une quantité décente de pratique pour vraiment pouvoir enseigner efficacement, et les professeurs d'informatique passent la majeure partie de leur carrière à travailler sur l'informatique, donc s'attendre à ce que la faculté d'informatique soit vraiment capable d'enseigner le TDD d'une manière cela ne va pas simplement confondre leurs élèves est assez irréaliste à mon avis.
Nous devons traiter l'informatique et le développement de logiciels professionnels comme des domaines distinctement distincts. Si votre objectif est d'apprendre l'informatique, vous ne devriez pas être obligé de payer des milliers de dollars pour apprendre à créer des sites Web en React incorrectement de la part de quelqu'un qui a passé les 30 dernières années de sa carrière à faire du graphique théorie sur un tableau noir. De même, si votre objectif est de devenir un ingénieur logiciel, je ne sais pas pourquoi vous voudriez passer 4 ans et des dizaines de milliers de dollars à apprendre ce qui n'est essentiellement qu'un domaine spécifique des mathématiques. C'est bien d'avoir une compréhension fondamentale dans le domaine, tout comme la façon dont quelqu'un qui conçoit un collecteur d'échappement doit comprendre une certaine quantité de physique, mais la personne qui conçoit le collecteur d'échappement n'a pas besoin d'une compréhension trop approfondie de la mécanique quantique, de la relativité restreinte, et l'électromagnétisme pour faire leur travail.
Si vous voulez être comptable, vous pouvez obtenir un diplôme en comptabilité et vos professeurs auront probablement tous été CPA à un moment ou à un autre. Si vous voulez être ingénieur en mécanique, vous pouvez obtenir un diplôme en génie mécanique et vos professeurs auront probablement tous été des ingénieurs agréés à un moment ou à un autre. Mais si vous voulez être ingénieur logiciel, tout diplôme en génie logiciel ne sera en fait qu'un diplôme en informatique avec certains de vos choix déjà choisis pour vous, et presque aucun de vos professeurs n'aura jamais été développeur de logiciels professionnel. Le diplôme en comptabilité ne fait pas partie du département de mathématiques et le diplôme en génie mécanique ne fait pas partie du département de physique, mais le diplôme en génie logiciel fera presque toujours partie du département d'informatique. Jusqu'à ce que le monde universitaire dans son ensemble sépare complètement ces deux domaines en différents départements dirigés par un personnel différent, je pense qu'il y aura toujours une longue liste de choses comme le TDD qui ne sont pas enseignées aux étudiants qui aspirent à devenir des ingénieurs logiciels.