Je pose cette question concernant les problèmes que j'ai rencontrés au cours de projets TDD. J'ai remarqué les problèmes suivants lors de la création de tests unitaires.
- Générer et maintenir des données factices
Il est difficile et irréaliste de conserver des données factices volumineuses. C’est encore plus difficile lorsque la structure de la base de données subit des modifications.
- Tester l'interface graphique
Même avec MVVM et la possibilité de tester l’interface graphique, il faut beaucoup de code pour reproduire le scénario de l’interface graphique.
- Tester l'entreprise
Je sais par expérience que TDD fonctionne bien si vous le limitez à une simple logique métier. Cependant, la logique métier complexe est difficile à tester car le nombre de combinaisons de tests (espace de test) est très grand.
- Contradiction dans les exigences
En réalité, il est difficile de saisir toutes les exigences analysées et conçues. Bien souvent, les exigences d’une note sont contradictoires car le projet est complexe. La contradiction est trouvée tard dans la phase de mise en œuvre. TDD exige que les exigences soient 100% correctes. Dans de tels cas, on pourrait s’attendre à ce que des exigences contradictoires soient prises en compte lors de la création des tests. Mais le problème est que ce n'est pas le cas dans des scénarios complexes.
J'ai lu cette question: Pourquoi le TDD fonctionne-t-il?
Le TDD fonctionne-t-il vraiment pour des projets d'entreprise complexes ou est-il limité au type de projet?
Réponses:
Faux.
Les tests unitaires ne nécessitent pas de "grandes" données fictives. Il faut assez de données factices pour tester les scénarios et rien de plus.
En outre, les programmeurs véritablement paresseux demandent aux experts en la matière de créer des feuilles de calcul simples des différents scénarios de test. Juste un tableur simple.
Ensuite, le programmeur paresseux écrit un script simple pour transformer les lignes de la feuille de calcul en scénarios de test unitaires. C'est assez simple, vraiment.
Lorsque le produit évolue, les feuilles de calcul des scénarios de test sont mises à jour et de nouveaux tests unitaires sont générés. Faites-le tout le temps. Ça marche vraiment.
Quelle? "Reproduire"?
Le but de TDD est de concevoir des objets pour la testabilité (développement d’essais). Si l'interface graphique est aussi complexe, elle doit être repensée pour être plus simple et plus testable. Plus simple signifie aussi plus rapide, plus facile à maintenir et plus flexible. Mais la plupart du temps plus simple signifie plus testable.
Cela peut être vrai
Cependant, demander aux experts en la matière de fournir les tests élémentaires sous une forme simple (comme une feuille de calcul) est vraiment utile.
Les feuilles de calcul peuvent devenir assez volumineuses. Mais ce n'est pas grave, car j’ai utilisé un simple script Python pour transformer les feuilles de calcul en scénarios de test.
Et. J'ai dû écrire certains cas de test manuellement car les feuilles de calcul étaient incomplètes.
Pourtant. Lorsque les utilisateurs ont signalé des "bogues", je leur ai simplement demandé quel scénario de test de la feuille de calcul était erroné.
À ce moment-là, les experts en la matière corrigeraient le tableur ou ajouteraient des exemples pour expliquer ce qui était censé se passer. Les rapports de bogue peuvent - dans de nombreux cas - être clairement définis comme un problème de scénario de test. En effet, de par mon expérience, définir le bogue comme un cas de test cassé rend la discussion beaucoup plus simple.
Plutôt que d'écouter les experts essayer d'expliquer un processus métier extrêmement complexe, ils doivent produire des exemples concrets du processus.
Ne pas utiliser TDD oblige absolument à ce que les exigences soient 100% correctes. Certains affirment que TDD peut tolérer des exigences incomplètes et changeantes, lorsqu'une approche non-TDD ne peut pas fonctionner avec des exigences incomplètes.
Si vous n'utilisez pas TDD, la contradiction est découverte tardivement lors de la phase de mise en œuvre.
Si vous utilisez TDD, la contradiction est trouvée plus tôt lorsque le code réussit certains tests et échoue pour d'autres tests. En effet, TDD vous fournit la preuve d’une contradiction plus tôt dans le processus, bien avant sa mise en œuvre (et les arguments lors des tests d’acceptation de l’utilisateur).
Vous avez un code qui passe certains tests et échoue d'autres. Vous ne regardez que ces tests et vous trouvez la contradiction. Cela fonctionne vraiment très bien dans la pratique, car les utilisateurs doivent maintenant discuter de la contradiction et produire des exemples cohérents et concrets du comportement souhaité.
la source
Oui
Ma première expérience avec TDD a été de travailler sur les composants middleware pour un téléphone portable basé sur Linux. Cela a finalement abouti à des millions de lignes de code source, qui ont à leur tour appelé environ 9 gigaoctets de code source pour divers composants open source.
Tous les auteurs de composants devaient proposer à la fois une API et un ensemble de tests unitaires, et les faire réviser par un comité de pairs. Personne ne s'attendait à des résultats parfaits, mais toutes les fonctions exposées au public devaient faire l'objet d'au moins un test. Une fois qu'un composant était soumis au contrôle de la source, tous les tests unitaires devaient toujours réussir (même s'ils le faisaient car le composant signalait faussement cela a fonctionné bien).
Nul doute que, du moins en partie à TDD et à l'insistance pour que tous les tests unitaires réussissent toujours, la version 1.0 est arrivée tôt, dans les limites du budget et avec une stabilité étonnante.
Après la publication de la version 1.0, les entreprises voulant pouvoir changer rapidement de périmètre à cause des demandes des clients, elles nous ont demandé de cesser de faire du TDD et ont supprimé l'exigence de réussite des tests unitaires. Il était étonnant de constater à quel point la qualité était à la baisse dans les toilettes et ensuite, le programme le suivait.
la source
removed the requirement that unit tests pass. It was astonishing how quickly quality went down the toilet, and then the schedule followed it.
- C'est comme si on disait à son pilote de F1 qu'il n'est pas autorisé à effectuer des arrêts aux stands, car cela prend trop de temps ... Idiot.Je dirais que plus le projet est complexe, plus vous retirez des avantages de TDD. Les principaux avantages sont les effets secondaires de la façon dont TDD vous oblige à écrire le code de manière beaucoup plus petite et bien plus indépendante. Les principaux avantages sont les suivants:
a) Vous obtenez beaucoup, beaucoup plus tôt la validation de votre conception, car votre boucle de rétroaction est beaucoup plus étroite en raison des tests effectués dès le départ.
b) Vous pouvez changer des éléments et voir comment le système réagit parce que vous avez construit une couverture de test tout au long de votre vie.
c) Le code fini sera bien meilleur en conséquence.
la source
Est-ce que TDD fonctionne vraiment pour des projets complexes?
Oui. On ne me dit pas que tous les projets fonctionnent bien avec TDD, mais la plupart des applications métier le sont bien, et je parie que celles qui ne fonctionnent pas bien lorsqu'elles sont écrites de manière purement TDD pourraient être écrites de manière ATDD sans problèmes majeurs.
Génération et mise à jour de données fictives
Conservez la petite taille et n’avez que ce dont vous avez besoin. Ce n’est pas ce qui fait peur, semble-t-il. Ne vous méprenez pas, c'est pénible. Mais cela en vaut la peine.
Test de l'interface graphique
Testez le MVVM et assurez-vous qu'il peut être testé sans la vue. J'ai trouvé que ce n'était pas plus difficile que de tester n'importe quel autre élément de la logique métier. Tester la vue dans le code, je ne le fais pas. Tout ce que vous testez, cependant, c’est la logique qui lie, ce qui, espérons-le, sera rapidement interceptée lorsque vous effectuez un test manuel rapide.
Test de l'entreprise
Pas jugé problématique. Beaucoup de petits tests. Comme je l'ai dit plus haut, certains cas (les solveurs de puzzle de Sudoku semblent être populaires) sont apparemment difficiles à réaliser.
TDD exige que les exigences soient correctes à 100%
Non. Où avez-vous eu cette idée? Toutes les pratiques agiles acceptent que les exigences changent. Vous devez savoir ce que vous faites avant de le faire, mais ce n'est pas la même chose que d'exiger que les exigences soient de 100%. TDD est une pratique courante dans Scrum, où les exigences (User Stories) ne sont, par définition, pas complètes à 100%.
la source
Tout d'abord, je pense que votre problème concerne davantage le test unitaire en général que le TDD, car je ne vois rien de vraiment spécifique au TDD (cycle test-first + cycle rouge-vert-refactor) dans ce que vous dites.
Qu'entendez-vous par données factices? Un simulacre est précisément censé contenir à peine toutes les données, c'est-à-dire aucun champ autre que le ou les deux nécessaires au test, et aucune dépendance autre que le système testé. La configuration d'une attente ou d'une valeur de retour fictive peut être effectuée en une seule ligne, donc rien de terrible.
Si vous voulez dire que la base de données subit des modifications sans que les modifications appropriées aient été apportées au modèle objet, les tests unitaires sont précisément là pour vous en avertir. Sinon, les modifications apportées au modèle doivent évidemment être reflétées dans les tests unitaires, mais avec les indications de compilation, rien de plus simple.
Vous avez raison, il n'est pas facile de tester l'interface utilisateur graphique (Affichage), et de nombreuses personnes s'en sortent bien (en outre, le test de l'interface graphique ne fait pas partie de TDD). En revanche, le test unitaire de votre contrôleur / présentateur / modèle de vue / quelle que soit la couche intermédiaire fortement recommandée, c’est en fait l’une des principales raisons pour lesquelles des modèles tels que MVC ou MVVM sont.
Si votre logique métier est complexe, il est normal que vos tests unitaires soient difficiles à concevoir. C'est à vous de les rendre aussi atomiques que possible, chacun ne testant qu'une seule responsabilité de l'objet à tester. Les tests unitaires sont d’autant plus nécessaires dans un environnement complexe, car ils fournissent un filet de sécurité garantissant que vous ne respectez pas les règles de gestion ou les exigences lorsque vous apportez des modifications au code.
Absolument pas. Un logiciel réussi requiert que les exigences soient 100% correctes;) Les tests unitaires ne font que refléter votre vision actuelle des exigences; si la vision est défectueuse, votre code et votre logiciel le seront aussi, tests unitaires ou non ... Et c'est là que brillent les tests unitaires: avec suffisamment de titres de tests explicites, vos décisions de conception et l'interprétation des exigences deviennent transparentes, ce qui facilite la votre doigt sur ce qui doit être changé la prochaine fois que votre client dit, "cette règle de gestion n'est pas tout à fait comme je le voudrais".
la source
Je dois rire quand j'entends quelqu'un se plaindre que la raison pour laquelle ils ne peuvent pas utiliser TDD pour tester leur application est parce que leur application est tellement compliquée. Quelle est l'alternative? Les singes de test martèlent-ils des acres de claviers? Laisser les utilisateurs être les testeurs? Quoi d'autre? Bien sûr que c'est difficile et complexe. Pensez-vous qu'Intel ne teste pas ses puces avant leur expédition? Comment est-ce que "tête-dans-le-sable" est?
la source
J'ai trouvé que TDD (et les tests unitaires en général) étaient pratiquement impossibles pour une raison liée: algorithmes complexes, nouveaux et / ou flous. Le problème que je rencontre le plus souvent dans les prototypes de recherche que j'écris est que je ne sais pas quelle est la bonne réponse autrement qu'en exécutant mon code. C’est trop compliqué pour comprendre raisonnablement à la main, sauf dans des cas ridiculement triviaux. Cela est particulièrement vrai si l'algorithme implique des heuristiques, des approximations ou du non-déterminisme. J'essaie toujours de tester les fonctionnalités de bas niveau dont dépend ce code et son utilisation s'appuie fortement sur des vérifications de cohérence. Ma méthode de test de dernier recours consiste à écrire deux implémentations différentes, idéalement dans deux langages différents, à l'aide de deux ensembles de bibliothèques différents, et à comparer les résultats.
la source
D'après mon expérience: Oui pour Unittests (test de modules / fonctionnalités isolément) car ceux-ci n'ont généralement pas les problèmes que vous avez mentionnés: (Gui, Mvvm, Business-Modell). Je n'ai jamais eu plus de 3 mocks / stubs pour remplir un unittest (mais peut-être que votre domaine nécessite plus).
Cependant, je ne suis pas sûr que TDD puisse résoudre les problèmes que vous avez mentionnés lors de l’intégration ou des tests de bout en bout avec des tests de type BDD.
Mais au moins certains problèmes peuvent être réduits .
Cela est vrai si vous souhaitez couvrir complètement le niveau de test d'intégration ou de bout en bout. Il serait peut-être plus facile de faire la couverture complète à un niveau unittest.
Exemple: vérification des autorisations d'utilisateurs complexes
Tester la fonction
IsAllowedToEditCusterData()
à un niveau de test d'intégration nécessiterait de demander à différents objets des informations sur l'utilisateur, le domaine, le client, l'environnement, etc.Se moquer de ces pièces est assez difficile. Cela est particulièrement vrai si
IsAllowedToEditCusterData()
doit connaître ces différents objets.Au niveau unittest, vous auriez une fonction
IsAllowedToEditCusterData()
qui prend par exemple 20 paramètres contenant tout ce que la fonction doit savoir. DepuisIsAllowedToEditCusterData()
n'a pas besoin de savoir quels champs auser
, adomain
, acustomer
, .... a c'est facile à tester.Quand j'ai dû implémenter,
IsAllowedToEditCusterData()
j'ai eu deux surcharges:Une surcharge qui ne fait rien d’autre que l’obtention de ces 20 paramètres et l’appel de surcharge avec les 20 paramètres permettant la prise de décision.
(ma
IsAllowedToEditCusterData()
n'avait que 5 paramètres et j'avais besoin de 32 combinaisons différentes pour le tester complètement)Exemple
la source
La réponse triste est que rien ne fonctionne vraiment pour les grands projets complexes!
Le TDD est aussi bon que n'importe quoi et meilleur que la plupart des autres, mais TDD seul ne garantira pas le succès d'un grand projet. Cela augmentera toutefois vos chances de succès. Surtout lorsqu'il est utilisé en combinaison avec d'autres disciplines de gestion de projet (vérification des exigences, cas d'utilisation, matrice de traitabilité des exigences, procédures de code, etc.).
la source
Rappelez-vous que les tests unitaires sont des spécifications appliquées . Ceci est particulièrement utile dans les projets complexes. Si votre ancienne base de code ne dispose d'aucun test pour la sauvegarder, personne n'osera rien changer car il craindra de tout casser.
"Wtf. Pourquoi cette branche de code est-elle même là? Je ne sais pas, peut-être que quelqu'un en a besoin, mieux vaut la laisser là-bas que de contrarier qui que ce soit ..." Au fil du temps, les projets complexes deviennent un terrain vague.
Avec les tests, tout le monde peut dire en toute confiance "J'ai apporté des changements radicaux, mais tous les tests réussissent encore." Par définition, il n'a rien cassé. Cela conduit à des projets plus agiles qui peuvent évoluer. Peut-être que l’une des raisons pour lesquelles nous avons encore besoin de personnes pour maintenir le COBOL est que les tests n’étaient plus populaires depuis: P
la source
J'ai vu un grand projet complexe échouer complètement quand TDD était utilisé exclusivement, c'est-à-dire sans au moins installer dans un débogueur / IDE. Les données factices et / ou les tests se sont révélés insuffisants. Les données réelles des clients bêta étaient sensibles et ne pouvaient être ni copiées ni enregistrées. Ainsi, l'équipe de développement n'a jamais pu réparer les bugs fatals qui se manifestaient lorsqu'on se dirigeait vers de vraies données, et l'ensemble du projet a été mis au rebut, tout le monde a été renvoyé.
Pour résoudre ce problème, il aurait été possible de le lancer dans un débogueur sur le site client, de confronter les données réelles, de parcourir le code, avec des points d'arrêt, de surveiller les variables, d'observer la mémoire, etc. Cependant, cette équipe, qui pensaient que leur code était apte à orner les plus belles tours d’ivoire, pendant une période de près d’un an, n’avait jamais lancé leur application. Cela m'a coupé l'esprit.
Alors, comme tout, l’équilibre est la clé. TDD peut être bon mais ne comptez pas uniquement sur lui.
la source
Je pense que oui, voir Test Driven Development fonctionne vraiment
la source
Si la combinaison du budget, des exigences et des compétences de l’équipe se trouve dans le quadrant de l’espace de projet «abandonne tout espoir à ceux qui entrent ici», alors, par définition, il est extrêmement probable que le projet échoue.
Peut-être les exigences sont-elles complexes et volatiles, l’infrastructure instable, l’équipe junior et le roulement de personnel élevé, ou encore l’architecte est un idiot.
Sur un projet TDD, le symptôme de cet échec imminent est que les tests ne peuvent pas être écrits dans les délais. vous essayez, pour découvrir «qui va prendre ce temps, et nous avons seulement que .
D'autres approches montreront des symptômes différents quand ils échoueront; le plus souvent la livraison d'un système qui ne fonctionne pas. La politique et les contrats détermineront si cela est préférable.
la source
TDD
Cela peut sembler aussi pénible au début, mais à long terme, ce serait votre meilleur ami, croyez-moiTDD
, cela rendra les applications faciles à maintenir et sécurisées à long terme.la source