Quand est-il approprié de ne pas effectuer de test unitaire?

139

Je travaille dans une petite entreprise en tant que développeur solo. Je suis le seul développeur de la société en fait. J'ai plusieurs projets (relativement) importants que j'ai écrits et maintenus régulièrement, et aucun d'entre eux n'a de tests pour les soutenir. Lorsque je commence de nouveaux projets, je me demande souvent si je devrais essayer une approche TDD. Cela semble être une bonne idée, mais honnêtement, je ne peux jamais justifier le travail supplémentaire que cela implique.

Je travaille dur pour être avant-gardiste dans ma conception. Je me rends bien compte qu'un jour, un autre développeur devra maintenir mon code, ou du moins le résoudre. Je fais des choses aussi simples que possible et je commente et documente des choses difficiles à comprendre. Et le fait est que ces projets ne sont ni si grands ni si compliqués qu'un développeur honnête aurait du mal à les comprendre.

Beaucoup d'exemples d'essais que j'ai vus vont jusqu'aux minuties, couvrant toutes les facettes du code. Étant donné que je suis le seul développeur et que je suis très proche du code dans l'ensemble du projet, il est beaucoup plus efficace de suivre un modèle de test en écriture puis en test manuel. Je trouve également que les exigences et les fonctionnalités changent assez souvent pour que le maintien des tests ajoute un frein considérable au projet. Temps qui pourrait autrement être utilisé pour résoudre les besoins de l'entreprise.

Je me retrouve donc chaque fois avec la même conclusion. Le retour sur investissement est trop faible.

J'ai parfois mis en place quelques tests pour vérifier que j'ai écrit un algorithme correctement, comme par exemple calculer le nombre d'années écoulées depuis qu'une personne travaille pour l'entreprise en fonction de sa date d'embauche. Mais du point de vue de la couverture de code, j'ai couvert environ 1% de mon code.

Dans ma situation, trouveriez-vous toujours un moyen de faire des tests unitaires une pratique régulière, ou ai-je le droit d'éviter ces frais généraux?

MISE À JOUR: J'ai omis quelques points à propos de ma situation: Mes projets sont tous des applications Web. Pour couvrir tout mon code, je devrais utiliser des tests d'interface utilisateur automatisés, et c'est un domaine pour lequel je ne vois toujours pas d'avantage important par rapport aux tests manuels.

Ken Pespisa
la source
1
Merci tout le monde. J'apprends beaucoup ici. Quelques points sur ma situation que j’ai laissés de côté: Mes projets sont tous des applications Web. Pour couvrir tout mon code, je devrais utiliser des tests d'interface utilisateur automatisés, et c'est un domaine pour lequel je ne vois toujours pas d'avantage important par rapport aux tests manuels.
Ken Pespisa
1
Transactis rencontre un vif succès en utilisant l'outil de test d'automatisation Web de Telerik. Nous avons déjà des dizaines de tests de navigateurs manuels précédemment convertis en automatisation. Les tests automatisés sont beaucoup plus rapides et sont également parfaits pour mettre en évidence les problèmes de performances que votre site Web peut rencontrer.
John Kaster
2
J'ai vu un projet qui tentait de tester automatiquement des pages Web complètes dans un navigateur. Autant que je sache, il n’a trouvé aucun des centaines de bugs graves détectés manuellement, et son développement et sa maintenance ont pris un temps considérable. (Utilisation de Selenium piloté par NUnit). Pire encore, certains tests s’arrêtent fréquemment pour des raisons autres que les problèmes, en raison des incompatibilités du navigateur et du cadre de test.
O'Rooney
1
Ce n'est pas vraiment une réponse, mais une observation ... votre argument contre les tests unitaires parce que "les exigences changent trop souvent" me rappelle l'argument inverse que j'entends là où je travaille: "nos programmes sont tellement statiques, quel est l'intérêt de tester ça ne change presque jamais de toute façon! " ;)
Bane
2
Les tests automatisés d'interface utilisateur d'applications Web ne sont pas des tests unitaires, ils sont une toute autre bête et je ne vous en voudrais pas si vous ne voulez pas les faire. Mais tout votre code d'entreprise devrait être dans le backend, et c'est ce que vous devriez tester.
Nyamiou The Galeanthrope

Réponses:

85

Beaucoup d'exemples d'essais que j'ai vus vont jusqu'aux minuties, couvrant toutes les facettes du code.

Alors? Vous n'êtes pas obligé de tout tester . Juste les choses pertinentes.

Étant donné que je suis le seul développeur et que je suis très proche du code dans l'ensemble du projet, il est beaucoup plus efficace de suivre un modèle de test en écriture puis en test manuel.

C'est en fait faux. Ce n'est pas plus efficace. C'est vraiment juste une habitude.

Ce que font les autres développeurs solo, c’est écrire un croquis ou un plan, écrire les scénarios de test, puis compléter le plan avec le code final.

C'est très très efficace.

Je trouve également que les exigences et les fonctionnalités changent assez souvent pour que le maintien des tests ajoute un frein considérable au projet.

C'est faux aussi. Les tests ne sont pas la traînée. Les changements requis sont la traînée.

Vous devez corriger les tests pour refléter les exigences. Que ce soit leur minutie ou de haut niveau; écrit en premier ou écrit en dernier.

Le code n'est pas terminé tant que les tests ne sont pas réussis. C'est la seule vérité universelle du logiciel.

Vous pouvez avoir un test d'acceptation limité "ici c'est".

Ou vous pouvez avoir des tests unitaires.

Ou vous pouvez avoir les deux.

Mais quoi que vous fassiez, il y a toujours un test pour démontrer que le logiciel fonctionne.

Je suggérerais qu'un peu de formalité et une belle suite d'outils de test unitaire rendent ce test beaucoup plus utile.

S.Lott
la source
8
J'aime votre première déclaration, pour tester uniquement les choses pertinentes. En ce qui concerne l'efficacité des tests manuels par rapport aux tests unitaires, je ne crois pas que ma déclaration soit entièrement fausse, pas plus que la vôtre. Il semble y avoir un équilibre à trouver entre les tests automatiques et manuels pour atteindre une efficacité maximale.
Ken Pespisa
9
@ Ken Pespisa: Désolé. J'ai bu le Kool-Aid TDD il y a environ deux ans (après 30 ans de test). Maintenant, je suis coincé sur test-first. Cela m'a rendu beaucoup, beaucoup plus productif parce que j'ai moins de réflexion à faire lors de la construction.
S.Lott
3
@ Ken Pespisa: Non. Les réponses sont équilibrées. Si vous demandiez s'il est juste de diviser par zéro, vous obtiendrez des réponses écrasantes qui penchent dans un sens pour une raison. Si vous demandiez s'il sqrt(-1)devrait s'agir d'un nombre entier, vous obtiendrez des réponses écrasantes dans un sens. La balance est autour de "comment" et "quel ordre". Le fait est que vous devez tester. Alors écrivez d'abord les tests et assurez-vous qu'ils fonctionnent.
S.Lott
21
Envisagez de tester l’unité de l’interface et non les détails de la mise en oeuvre. Testez les limites et les cas frontières. Testez le code risqué. Beaucoup de code est assez simple pour être vérifié par inspection, bien que l'inspection de votre code soit plus sujette aux erreurs que l'inspection du code de quelqu'un d'autre. La première fois que les tests manuels peuvent être plus efficaces, la dixième fois, les tests automatisés sont bien avancés.
BillThor
10
"Le code n'est pas terminé tant que les tests ne sont pas passés" - Pas vraiment, Messieurs. Le code commence lorsqu'il passe les tests. Le code n’est terminé que s’il est en ligne depuis un an ou deux et est soumis à des tests de résistance et à des tests d’intégration avec une base d’utilisateurs importante, active et impatiente. C'est le seul test qui compte vraiment.
Vecteur
108

Imaginez que vous ayez une série de tests qui pourraient fonctionner dans les yeux et allumeraient une lumière verte ou rouge. Imaginez que cette suite de tests a tout testé ! Imaginez que tout ce que vous avez à faire pour exécuter la suite de tests consiste à taper ^ T. Quel pouvoir cela vous donnerait-il?

Pourriez-vous modifier le code sans craindre de casser quelque chose? Pourriez-vous ajouter une nouvelle fonctionnalité sans craindre de casser une ancienne fonctionnalité? Pourriez-vous nettoyer le code en désordre rapidement sans crainte de dommages?

Oui, vous pourriez faire toutes ces choses! Et qu'adviendrait-il de votre code avec le temps? Cela deviendrait de plus en plus propre car il n'y aurait aucun risque à le nettoyer.

Imaginons que vous ayez une petite fée sur votre épaule. Chaque fois que vous écriviez une ligne de code, la fée ajoutait quelque chose à la suite de tests qui vérifiait que cette ligne de code avait les résultats escomptés. Ainsi, toutes les deux secondes, vous pouvez taper ^ T et voir que la dernière ligne de code que vous avez écrite a fonctionné.

Combien de débogage pensez-vous que vous feriez?

Si cela ressemble à de la fantaisie, vous avez raison. Mais la réalité n’est pas très différente. Remplacez le clignement des yeux par quelques secondes et la fée par la discipline TDD, et vous l'aurez compris.

Supposons que vous revenez à un système que vous avez construit il y a un an et que vous avez oublié comment créer l'un des objets centraux. Il existe des tests qui créent cet objet de toutes les manières possibles. Vous pouvez lire ces tests et rafraîchir votre mémoire. Besoin d'appeler une API? Il existe des tests qui appellent cette API de toutes les manières possibles. Ces tests sont de petits documents écrits dans une langue que vous comprenez. Ils sont complètement sans ambiguïté. Ils sont si formels qu'ils exécutent. Et ils ne peuvent pas être désynchronisés avec l'application!

Ne vaut pas l'investissement? Tu rigoles! Comment quelqu'un pourrait-il pas vouloir cette suite de tests? Faites-vous une faveur et arrêtez de chicaner sur la bêtise. Apprenez à bien faire le TDD et observez à quelle vitesse vous allez, et à quel point votre code est plus propre.

Oncle Bob.
la source
29
Wow, l'oncle Bob? C'est génial d'avoir vos pensées ici. Je suis d'accord avec vous sur les avantages du TDD, il n'y a vraiment aucun argument à faire. La question concerne l'investissement de temps et le retour sur investissement. Ce n'est pas stupide pour moi de considérer ces choses. Imaginez qu’un projet mette 50% plus de temps à terminer avec TDD que sans, et la fée me dit que cela ne me fera gagner que 10% de temps sur les tests manuels au cours de la vie du projet. Cela peut sembler un fantasme, mais je le vois comme totalement plausible avec certains projets.
Ken Pespisa
11
@Ken "Imaginez qu'un projet mette 50% plus de temps à terminer avec TDD que sans". Cela ressemble EXACTEMENT à du fantasme pour moi. En fait, il semble que vous ayez inventé cette image sur-le-champ sans aucune preuve à l'appui.
Rein Henrichs
18
@ Rein Henrichs - Bien sûr, j'ai composé le numéro, c'était une déclaration hypothétique. Je tiens à souligner que TDD ajoute beaucoup de temps à un projet et que je dois déterminer si je vais obtenir quelque chose de valeur égale ou meilleure en retour. Vous n'êtes pas obligé de me convaincre des valeurs de TDD, j'en suis convaincu. Mais ce n'est pas une panacée.
Ken Pespisa
11
@ Rein, quelle est exactement la "preuve disponible"? S'il vous plaît élaborer.
Ken Pespisa
22
@Uncle Bob "Remplacez le clignement des yeux par quelques secondes": Vous plaisantez, bien sûr. TDD est un bon outil, mais vous ne devez tester que les composants pertinents, sinon vous passerez plus de temps à maintenir des tests qu’à effectuer un développement sérieux. Cela est particulièrement vrai lorsque les exigences changent très rapidement: vous écrivez et jetez constamment des tests pour des classes qui changent tout le temps. Je ne dis pas que le TDD est mauvais, il doit simplement être utilisé judicieusement et non pas appliqué mécaniquement, comme vous semblez le suggérer.
Giorgio
34

L'erreur que vous faites est que vous voyez les tests comme un investissement de temps sans retour immédiat. Cela ne fonctionne pas nécessairement comme ça.

Premièrement, l'écriture de tests vous concentre vraiment sur ce que cette partie de votre code doit faire.

Deuxièmement, leur exécution révèle des bugs qui seraient sinon apparus lors des tests.

Troisièmement, les exécuter montre parfois des bugs qui, autrement, ne seraient pas détectés lors des tests et vous auraient vraiment mordu dans la production.

Quatrièmement, si vous rencontrez un bogue avec un système en cours d’exécution et créez un test unitaire, vous ne pourrez pas réintroduire ce bogue ultérieurement. Cela peut être une très grande aide. Les insectes réintroduits sont courants et très ennuyeux.

Cinquièmement, si vous avez besoin de transmettre le code à quelqu'un d'autre, une suite de tests leur facilitera la vie. De plus, si vous avez ignoré un projet et que vous y revenez après quelques années, vous n'en serez plus aussi proche et cela vous sera utile également.

Mon expérience a toujours été que, tout au long du développement d'un projet, des tests unitaires décents ont toujours rendu le processus plus rapide et plus fiable.

glénatron
la source
2
@Ken, les suites de tests sont des spécifications sous une forme exécutable.
32

Les gars de JUnit (framework de test d'unité Java) ont pour philosophie que s'il est trop simple à tester, ne le testez pas . Je recommande fortement de lire leur FAQ sur les meilleures pratiques , car elle est assez pragmatique.

TDD est un processus différent d’écriture de votre logiciel. Le principe de base des tests unitaires est que vous passerez moins de temps dans le débogueur à parcourir le code et à déterminer plus rapidement si la modification de votre code annule accidentellement quelque chose d'autre dans le système. Cela correspond au TDD. Le cycle TDD est comme ceci:

  1. Écrire un test
  2. Regardez-le échouer (prouver que vous avez quelque chose à faire)
  3. Écrivez simplement ce qui est nécessaire pour que le test réussisse - sans plus.
  4. Regarde le passer (yay!)
  5. Refactor (le rendre meilleur)
  6. Laver, rincer et répéter

Ce qui est moins évident dans l’application de TDD, c’est que cela change la façon dont vous écrivez le code . En vous forçant à réfléchir à la manière de tester / valider le fonctionnement du code, vous écrivez du code testable. Et puisque nous parlons de tests unitaires, cela signifie généralement que votre code devient plus modulaire. Pour moi, le code modulaire et testable est une grande victoire dès le départ.

Maintenant, avez-vous besoin de tester des choses comme les propriétés C #? Imaginez une propriété définie comme ceci:

bool IsWorthTesting {get; set;}

La réponse serait "non", cela ne vaut pas la peine d'être testé, car vous testez actuellement la fonctionnalité linguistique. Ayez juste confiance que les gars de la plate-forme C # ont eu raison. En outre, si cela échouait, que pourriez- vous faire pour le réparer?

En outre, vous constaterez que certaines parties de votre code nécessiteront trop d’efforts pour être testées correctement. Cela signifie que ne le faites pas, mais assurez-vous de tester le code qui utilise / est utilisé par le problème épineux:

  • Les exceptions vérifiées qui ne peuvent se produire que si une installation a mal tourné. Java en a une tonne. Vous devez écrire un bloc catch ou déclarer l’exception vérifiée même s’il n’ya aucun moyen de l’échouer sans pirater les fichiers installés.
  • Les interfaces des utilisateurs. La recherche du contrôle sous test et l'appel des événements appropriés pour simuler les actions d'un utilisateur sont très gênants, voire impossibles. Cependant, si vous utilisez le modèle Modèle / Vue / Contrôleur, vous pouvez vous assurer que votre modèle et vos contrôleurs sont testés et laisser la partie vue à un test manuel.
  • Interactions client / serveur. Ce n'est plus un test unitaire, mais un test d' intégration . Ecrivez toutes les parties qui permettent d'envoyer et de recevoir des messages par fil, mais ne le faites pas en réalité. Une bonne approche consiste à réduire la responsabilité du code qui parle en réalité aux communications brutes. Dans votre code de test unitaire, simulez un objet de communication pour vous assurer que les services se comportent comme prévu.

Croyez-le ou non, TDD vous aidera à atteindre un rythme de développement durable. Ce n'est pas à cause de la magie, mais plutôt parce que vous avez une boucle de rétroaction serrée et que vous êtes en mesure d'attraper rapidement des erreurs vraiment stupides. Le coût de la correction de ces erreurs est essentiellement constant (du moins suffisant pour la planification), car les petites erreurs ne deviennent jamais de grandes erreurs. Comparez cela à la nature éclatante des sprints de purge de binge / débogage de code.

Berin Loritsch
la source
24

Vous devez équilibrer le coût des tests avec le coût des bugs.

L'écriture d'un test unitaire de 10 lignes pour une fonction qui ouvre un fichier, où l'échec est "fichier introuvable" est inutile.

Une fonction qui fait quelque chose de complexe à une structure de données complexe - alors évidemment oui.

La partie la plus délicate est entre les deux. Mais rappelez-vous que la valeur réelle des tests unitaires ne consiste pas à tester une fonction particulière, mais à tester les interactions complexes qui les unissent. Ainsi, un test unitaire qui détecte qu'un changement dans un bit de code, casse certaines fonctions dans un module différent à une distance de 1000 lignes, vaut son pesant poids en café.

Martin Beckett
la source
23

Tester, c'est jouer.

Créer un test est un pari sur le fait que le coût des bogues dans une unité qui surviennent et ne pas les rattraper avec ce test (maintenant et lors de toutes les révisions de code futures) est supérieur au coût de développement du test. Ces coûts de développement de tests incluent des éléments tels que la paie pour une ingénierie de test supplémentaire, un délai de commercialisation plus long, des coûts d’opportunité perdus du fait de ne pas coder d’autres éléments, etc.

Comme tout pari, parfois vous gagnez, parfois vous perdez.

Parfois, un logiciel en retard avec beaucoup moins de bogues l'emporte sur des choses rapides mais boguées qui arrivent en premier sur le marché. Parfois le contraire. Vous devez examiner les statistiques de votre domaine et déterminer combien de joueurs veulent jouer.

Il est possible que certains types de bogues ne soient pas générés, ou sortent de tout test de validation préalable, de manière à ne pas, statistiquement, valoir le temps nécessaire pour créer des tests spécifiques supplémentaires. Mais parfois, le coût d'un bug est tellement élevé (médical, nucléaire, etc.) qu'une entreprise doit prendre un pari perdant (similaire à l'achat d'une assurance). De nombreuses applications n'ont pas un coût d'échec aussi élevé, et n'ont donc pas besoin de la couverture d'assurance non rentable plus élevée. Les autres font.

hotpaw2
la source
3
Bonne réponse. Un des rares qui répond vraiment à ma question initiale. Je me suis immergé dans le monde des tests depuis que j'ai écrit ce billet (je l'aime d'ailleurs.) Je dois le comprendre davantage avant de pouvoir vraiment savoir quand l'utiliser (ou non). Pour bon nombre des raisons énoncées ici, je préférerais l’utiliser tout le temps. Mais cela dépendra en fin de compte de la rapidité avec laquelle je vais y arriver, car au final, c’est un pari de mon temps, qui est sous le contrôle de mon entreprise / client, et ils se concentrent souvent sur les coins inférieurs du projet triangle: en. wikipedia.org/wiki/Project_triangle
Ken Pespisa
10

Mon conseil est de ne tester que le code sur lequel vous voulez travailler correctement.

Ne testez pas le code pour lequel vous voulez être bogué et vous poser des problèmes par la suite.

Nick Hodges
la source
9
Cela me rappelle le dicton de mon dentiste: vous n’avez pas besoin de passer la soie dentaire toutes les dents, mais celles que vous voulez garder.
Ken Pespisa
J'avoue que c'est ce qui m'a fait penser à cela. ;-)
Nick Hodges
8

Je me demande souvent si je devrais essayer une approche TDD. Cela semble être une bonne idée, mais honnêtement, je ne peux jamais justifier le travail supplémentaire que cela implique.

TDD et tests unitaires ne sont pas la même chose.

Vous pouvez écrire du code, puis ajouter des tests unitaires ultérieurement. Ce n'est pas un TDD et représente beaucoup de travail supplémentaire.

TDD est la pratique de coder dans une boucle de lumière rouge. Lumière verte. Itérations de refactoring.

Cela signifie écrire des tests pour du code qui n'existe pas encore, regarder les tests échouer, corriger le code pour que les tests fonctionnent, puis rendre le code "correct". Cela vous évite souvent de travailler

L'un des avantages de TDD est qu'il réduit le besoin de penser à des anecdotes. Des choses comme les erreurs off-by-one disparaissent. Vous n'avez pas à parcourir la documentation de l'API pour savoir si la liste renvoyée commence à 0 ou 1, faites-le.

Paul Butcher
la source
Pourriez-vous préciser comment les erreurs off-by-one disparaissent? Voulez-vous dire que vous pouvez obtenir plus rapidement votre réponse sur le fait de savoir si l'index d'un tableau est basé sur zéro ou sur un via des tests plutôt que de chercher dans la documentation? Il me semble peu probable - je suis assez rapide sur Google :)
Ken Pespisa Le
1
En réalité, l'écriture de TDD est un excellent moyen d'explorer une API (y compris une base de code héritée, dans le but de documenter les fonctionnalités).
Frank Shearar
C'est aussi très utile si cette API change jamais ... Vous avez soudainement des tests qui échouent :-)
bitsoflogic Le
@ Ken Pespisa, c'est certainement plus rapide - écrivez le code en fonction de si vous pensez qu'il est 0 ou 1, exécutez-le, corrigez-le si nécessaire. La plupart du temps, vous aurez raison et vous auriez évité de chercher, si vous vous trompez, vous savez en moins de 10 secondes.
Paul Butcher
Avantage très intéressant. Je genre de comme ça.
Ken Pespisa
3

J'ai travaillé sur un système où nous avons presque tout testé. Les exécutions notables à tester étaient les codes de sortie PDF et XLS.

Pourquoi? Nous avons pu tester les parties qui ont rassemblé les données et construit le modèle utilisé pour créer la sortie. Nous avons également pu tester les éléments permettant de déterminer les éléments du modèle destinés aux fichiers PDF. Nous n'avons pas été en mesure de vérifier si le fichier PDF paraissait correct car il était totalement subjectif. Nous n'avons pas été en mesure de vérifier que toutes les parties d'un fichier PDF étaient lisibles par un utilisateur typique, car elles étaient également subjectives. Ou si le choix entre les graphiques à barres et à secteurs était correct pour l'ensemble de données.

Si le résultat doit être subjectif, il y a peu de tests unitaires qui permettent de faire ce qui en vaut la peine.

sal
la source
En fait, ce type de test est probablement un "test d'intégration". Et oui, les tests d'intégration sont beaucoup plus difficiles que les tests unitaires, et l'une des raisons est que parfois les règles pour ce qui est "correct" sont très compliquées, voire subjectives.
Sleske
2

Dans bien des cas, un test d'écriture, puis manuel, ne prend pas plus de temps que d'écrire quelques tests. Les économies de temps résultent de la possibilité de réexécuter ces tests à tout moment.

Pensez-y: si vous avez une couverture de fonctionnalités décente avec vos tests (à ne pas confondre avec la couverture de code), et disons que vous avez 10 fonctionnalités - cliquer sur un bouton signifie que vous avez à peu près 10 répétitions de vos tests ... pendant que vous vous asseyez et sirotez votre café.

Vous n'avez pas non plus à tester les minutae. Vous pouvez écrire des tests d'intégration qui couvrent vos fonctionnalités si vous ne voulez pas entrer dans les détails - IMO, certains tests unitaires sont trop détaillés pour tester le langage et la plate-forme, et non le code.

TL; DR Ce n'est vraiment jamais approprié car les avantages sont tout simplement trop bons.

Steven Evers
la source
2

Deux très bonnes réponses que j'ai rencontrées sont ici:

  1. Quand faire le test unitaire contre le test manuel
  2. Quoi ne pas tester en matière de tests unitaires?

Les justifications pour éviter les frais généraux perçus:

  • Économie immédiate de temps / coûts pour votre entreprise
  • Économie potentielle de temps / coût en dépannage / maintenabilité / extension à long terme même après votre départ.

Ne voudriez-vous pas laisser un bon produit de votre côté comme gage de la qualité de votre travail? En termes égoïstes, n’est-ce pas mieux pour vous que vous faites?

Aditya P
la source
1
Bonne question à la fin. Je suis absolument fier de mon travail et mes applications fonctionnent très bien (si je peux être si audacieux). Mais vous avez raison, ils pourraient être encore meilleurs avec l’aide de tests. Je pense que mon objectif ici est d’essayer d’intégrer le plus de tests utiles possible dans les délais dont je dispose pour travailler sur le projet, sans pour autant être obsédé par la couverture de code.
Ken Pespisa
1

Les développeurs professionnels écrivent des tests unitaires car, à long terme, ils permettent de gagner du temps. Vous allez tester votre code tôt ou tard, et si ce n'est pas le cas de vos utilisateurs, et si vous devez corriger les bogues plus tard, ils seront plus difficiles à corriger et auront plus d'effets d'entraînement.

Si vous écrivez du code sans tests ni bugs, alors tout va bien. Je ne crois pas que vous puissiez écrire un système non trivial avec zéro bogue, alors je suppose que vous le testez d'une manière ou d'une autre.

Les tests unitaires sont également essentiels pour éviter les régressions lorsque vous modifiez ou refactorisez du code ancien. Ils ne prouvent pas que votre changement n'a pas cassé l'ancien code, mais ils vous donnent beaucoup de confiance (tant qu'ils passent, bien sûr :))

Je ne voudrais pas revenir en arrière et écrire tout un lot de tests pour le code que vous avez déjà fourni, mais la prochaine fois que vous devrez modifier une fonctionnalité, je vous suggérerais d'essayer d'écrire des tests pour ce module ou cette classe, obtenez une couverture allant jusqu'à 70%. + avant d'appliquer les modifications. Voyez si cela vous aide.

Si vous essayez et que vous pouvez honnêtement dire que cela n’a pas été une aide, alors je pense qu’il existe suffisamment de preuves dans l’industrie pour les aider à valoriser au moins votre tentative d’approche.

Steve
la source
J'aime les idées sur la prévention des régressions et l'ajout de confiance. Ce sont exactement les raisons pour lesquelles je voudrais ajouter des tests.
Ken Pespisa
1

Il semble que la plupart des réponses soient pro-TDD, même si la question ne portait pas sur le TDD mais sur les tests unitaires en général.

Il n'y a pas de règle complètement objective derrière ce qui doit être testé ou non. Mais il semble parfois que de nombreux programmeurs n'effectuent pas de tests unitaires:

  1. Méthodes privées

Selon votre philosophie de POO, vous pouvez créer des méthodes privées pour découpler des routines complexes de vos méthodes publiques. Les méthodes publiques sont généralement destinées à être appelées dans de nombreux endroits et sont souvent utilisées, et les méthodes privées ne sont réellement appelées que par une ou deux méthodes publiques dans une classe ou un module, dans un but très spécifique. Il est généralement suffisant d'écrire des tests unitaires pour les méthodes publiques, mais pas les méthodes privées sous-jacentes qui permettent à la magie de se produire. Si quelque chose ne va pas avec une méthode privée, vos tests unitaires de méthode publique devraient suffire à détecter ces problèmes.

  1. Ce que vous savez déjà devrait fonctionner (ou testé par quelqu'un d'autre)

Beaucoup de nouveaux programmeurs s'opposent à cela lorsqu'ils apprennent à tester pour la première fois et pensent qu'ils doivent tester chaque ligne exécutée. Si vous utilisez une bibliothèque externe et que sa fonctionnalité est bien testée et documentée par ses auteurs, il est généralement inutile de tester la fonctionnalité spécifique dans les tests unitaires. Par exemple, une personne peut écrire un test pour s'assurer que son modèle ActiveRecord conserve la valeur correcte pour un attribut avec un rappel "before_save" à la base de données, même si ce comportement est déjà testé de manière approfondie dans Rails. La ou les méthodes que le rappel appelle, peut-être, mais pas le comportement du rappel lui-même. Tous les problèmes sous-jacents liés aux bibliothèques importées seraient mieux révélés par des tests d'acceptation plutôt que par des tests unitaires.

Les deux peuvent s'appliquer que vous soyez en TDD ou non.

Ravenstine
la source
0

Ken, moi-même et de nombreux autres développeurs sommes parvenus à la même conclusion à plusieurs reprises au cours de notre carrière.

La vérité que je crois que vous découvrirez (comme beaucoup d’autres), c’est que l’investissement initial dans la rédaction de tests pour votre application peut sembler décourageant, mais si bien écrit et ciblé sur les parties correctes de votre code, ils peuvent vraiment économiser une tonne. de temps.

Mon gros problème était avec les cadres de test disponibles. Je n'avais jamais vraiment eu l'impression qu'ils correspondaient à ce que je cherchais, alors j'ai simplement présenté ma propre solution très simple. Cela m'a vraiment aidé à comprendre le «côté obscur» des tests de régression. Je vais partager un pseudo extrait de base de ce que j'ai fait ici et j'espère que vous pourrez trouver une solution qui vous convient.

public interface ITest {
    public string Name {
        get;
    }
    public string Description {
        get;
    }
    public List<ITest> SubTests {
        get;
    }
    public TestResult Execute();
}

public class TestResult {
    public bool Succesful {
        get;
        set;
    }

    public string ResultMessage {
        get;
        set;
    }

    private Dictionary<ITest, TestResult> subTestResults = new Dictionary<ITest, TestResult>();
    public Dictionary<ITest, TestResult> SubTestResults {
        get {
            return subTestResults;
        }
        set {
            subTestResults = value;
        }
    }
}

Après cela, la seule difficulté consiste à déterminer le niveau de granularité qui vous convient le mieux, quel que soit votre projet.

Construire un carnet d'adresses nécessitera évidemment beaucoup moins de tests qu'un moteur de recherche d'entreprise, mais les principes fondamentaux ne changent pas vraiment.

Bonne chance!

Adam Carstensen
la source
Je pense qu'avec le temps, je saurai quel niveau de granularité est le meilleur. Il est bon d’entendre d’autres personnes qui créent régulièrement des tests qu’elles l’approche de manière sensée et ne pas écrire de manière robotique des tests pour chaque résultat imaginable. Ma première introduction aux tests était à ce niveau où tout devait être testé. En fait, tout le concept de TDD semble suivre ce mantra.
Ken Pespisa
Je pense que l’utilisation d’un framework comme SubSpec (inspiré de BDD) pourrait vous être utile, ce qui vous permettra d’obtenir l’isolation Assert ("SubTest") lors de la configuration du contexte.
Johannes Rudolph