unit-testing - intégration - test unitaire php




Les tests unitaires en valent-ils la peine? (20)

Je travaille pour intégrer les tests unitaires dans le processus de développement de l'équipe sur laquelle je travaille et il y a des sceptiques. Quels sont les bons moyens de convaincre les développeurs sceptiques de l'équipe de la valeur de Unit Testing? Dans mon cas particulier, nous ajouterions des tests unitaires à mesure que nous ajouterions des fonctionnalités ou des bogues corrigés. Malheureusement, notre base de code ne se prête pas à des tests faciles.


thetalkingwalnut demande:

Quels sont les bons moyens de convaincre les développeurs sceptiques de l'équipe de la valeur de Unit Testing?

Tout le monde ici va accumuler beaucoup de raisons à l'improviste pourquoi les tests unitaires sont bons. Cependant, je trouve souvent que le meilleur moyen de convaincre quelqu'un de quelque chose est d' écouter son argumentation et de l'aborder point par point. Si vous les écoutez et les aidez à exprimer leurs préoccupations, vous pouvez les aborder et peut-être les convertir à votre point de vue (ou, à tout le moins, les laisser sans jambe pour se tenir debout). Qui sait? Peut-être qu'ils vous convaincront pourquoi les tests unitaires ne sont pas adaptés à votre situation. Pas probable, mais possible. Peut-être que si vous publiez leurs arguments contre des tests unitaires, nous pouvons aider à identifier les contre-arguments.

Il est important d'écouter et de comprendre les deux côtés de l'argument. Si vous essayez d'adopter des tests unitaires avec trop de zèle sans tenir compte des préoccupations des gens, vous finirez avec une guerre de religion (et probablement des tests unitaires sans valeur). Si vous l'adoptez lentement et commencez par l'appliquer là où vous verrez le plus d'avantages au moindre coût, vous pourrez peut-être démontrer la valeur des tests unitaires et avoir une meilleure chance de convaincre les gens. Je me rends compte que ce n'est pas aussi facile que ça en a l'air - il faut généralement du temps et des mesures précises pour élaborer un argument convaincant.

Les tests unitaires sont un outil, comme les autres, et doivent être appliqués de manière à ce que les avantages (bugs de capture) l'emportent sur les coûts (l'effort de les écrire). Ne les utilisez pas si / où ils n'ont pas de sens et rappelez-vous qu'ils ne sont qu'une partie de votre arsenal d'outils (par exemple inspections, assertions, analyseurs de code, méthodes formelles, etc.). Ce que je dis à mes développeurs est ceci:

  1. Ils peuvent passer un test pour une méthode s'ils ont un bon argument pour expliquer pourquoi cela n'est pas nécessaire (par exemple trop simple pour le valoir ou trop difficile pour le valoir) et comment la méthode sera vérifiée (par exemple, inspection, assertions , méthodes formelles, tests interactifs / d'intégration). Ils doivent considérer que certaines vérifications comme les inspections et les preuves formelles sont faites à un moment donné et doivent ensuite être répétées chaque fois que le code de production change, tandis que les tests unitaires et les assertions peuvent être utilisés comme tests de régression. ). Parfois, je suis d'accord avec eux, mais plus souvent je vais débattre de la question de savoir si une méthode est vraiment trop simple ou trop difficile à tester unitaire.

    • Si un développeur fait valoir qu'une méthode semble trop simple pour échouer, cela ne vaut-il pas la peine de prendre les 60 secondes nécessaires pour rédiger un simple test unitaire de 5 lignes? Ces 5 lignes de code fonctionneront tous les soirs (vous faites des batailles nocturnes, n'est-ce pas?) Pour l'année suivante ou plus et cela en vaudra la peine si seulement une fois arrive à attraper un problème qui a pris 15 minutes ou plus pour identifier et déboguer. En outre, écrire les tests unitaires faciles augmente le nombre de tests unitaires, ce qui rend le développeur bien paraître.

    • D'un autre côté, si un développeur argumente qu'une méthode semble trop difficile à tester (ne vaut pas l'effort significatif requis), c'est peut-être une bonne indication que la méthode doit être divisée ou refactorisée pour tester les parties faciles. Habituellement, ce sont des méthodes qui s'appuient sur des ressources inhabituelles comme les singletons, l'heure actuelle, ou des ressources externes comme un ensemble de résultats de base de données. Ces méthodes doivent généralement être refactorisées dans une méthode qui récupère la ressource (par exemple, les appels getTime ()) et une méthode qui prend la ressource en argument (par exemple, prend l'horodatage comme paramètre). Je les laisse passer le test de la méthode qui récupère la ressource et écrit à la place un test unitaire pour la méthode qui prend maintenant la ressource en argument. Habituellement, cela rend l'écriture du test unitaire beaucoup plus simple et donc intéressante à écrire.

  2. Le développeur doit tracer une «ligne dans le sable» dans la mesure où leurs tests unitaires devraient être complets. Plus tard dans le développement, chaque fois que nous trouvons un bug, ils devraient déterminer si des tests unitaires plus complets auraient permis de résoudre le problème. Si c'est le cas et si de tels bugs surgissent à plusieurs reprises, ils doivent déplacer la «ligne» vers l'écriture de tests unitaires plus complets dans le futur (en commençant par ajouter ou étendre le test unitaire du bogue actuel). Ils ont besoin de trouver le bon équilibre.

Il est important de réaliser les tests unitaires ne sont pas une balle d'argent et il y a trop de tests unitaires. Sur mon lieu de travail, chaque fois que nous faisons des leçons apprises, j'entends inévitablement «nous devons écrire plus de tests unitaires». La direction acquiesce d'un signe de tête parce qu'on lui a cogné la tête que «tests unitaires» == «bien».

Cependant, nous devons comprendre l'impact de «plus de tests unitaires». Un développeur ne peut écrire que ~ N lignes de code par semaine et vous devez déterminer quel pourcentage de ce code doit être un code de test unitaire par rapport au code de production. Un poste de travail laxiste peut avoir 10% du code comme tests unitaires et 90% du code comme code de production, ce qui donne un produit avec beaucoup de fonctionnalités (bien que très buggué) (pensez MS Word). D'autre part, un magasin strict avec 90% de tests unitaires et 10% de code de production aura un produit solide avec peu de fonctionnalités (pensez "vi"). Vous pouvez ne jamais entendre des rapports sur le fait que ce dernier produit plante, mais cela a probablement autant à voir avec le produit qui ne se vend pas très bien autant que cela a à voir avec la qualité du code.

Pire encore, peut-être la seule certitude dans le développement de logiciels est que "le changement est inévitable". Supposons que le magasin strict (90% de tests unitaires / 10% de code de production) crée un produit ayant exactement 2 caractéristiques (en supposant 5% du code de production == 1 caractéristique). Si le client arrive et modifie 1 des fonctionnalités, alors ce changement détruit 50% du code (45% des tests unitaires et 5% du code de production). La boutique laxiste (10% tests unitaires / 90% code de production) a un produit avec 18 fonctionnalités, dont aucune ne fonctionne très bien. Leur client réorganise complètement les exigences pour 4 de leurs fonctionnalités. Même si le changement est 4 fois plus important, seulement la moitié de la base du code est détruite (~ 25% = ~ 4,4% de tests unitaires + 20% de code de production).

Ce que je veux dire, c'est que vous devez communiquer que vous comprenez l'équilibre entre trop peu et trop de tests unitaires - essentiellement que vous avez réfléchi aux deux côtés de la question. Si vous pouvez convaincre vos pairs et / ou votre gestion de cela, vous gagnez de la crédibilité et avez peut-être une meilleure chance de les gagner.


Avec la suite de tests unitaires, on peut apporter des modifications au code tout en laissant le reste des fonctionnalités intactes. C'est un grand avantage. Utilisez-vous la suite de tests unitaires et de test de régression lorsque vous avez fini de coder une nouvelle fonctionnalité.


J'ai écrit un très gros article sur le sujet. J'ai constaté que les tests unitaires ne valent pas le travail et qu'ils sont généralement supprimés lorsque les délais se rapprochent.

Au lieu de parler des tests unitaires du point de vue de la vérification «test après», nous devrions examiner la vraie valeur trouvée lorsque vous avez décidé d'écrire une spécification / un test / une idée avant la mise en œuvre.

Cette idée simple a changé la façon dont j'écris les logiciels et je ne reviendrai pas à l'ancienne.

Comment tester le premier développement a changé ma vie


J'ai découvert TDD il y a quelques années, et j'ai depuis écrit tous mes projets pour animaux de compagnie en l'utilisant. J'ai estimé qu'il faut à peu près le même temps pour TDD un projet qu'il faut pour le cowboy ensemble, mais j'ai tellement confiance dans le produit final que je ne peux pas aider un sentiment d'accomplissement.

Je pense aussi que cela améliore mon style de design (beaucoup plus orienté interface au cas où je devrais me moquer des choses ensemble) et, comme l'écrit le post vert en haut, ça aide à "coder la constipation": quand vous ne savez pas quoi pour écrire ensuite, ou vous avez une tâche ardue en face de vous, vous pouvez écrire petit.

Enfin, je trouve que l'application la plus utile de TDD est de loin dans le débogage, ne serait-ce que parce que vous avez déjà développé un cadre d'interrogation avec lequel vous pouvez inciter le projet à produire le bug de façon reproductible.


J'ai récemment vécu exactement la même expérience dans mon lieu de travail et j'ai trouvé que la plupart d'entre eux connaissaient les avantages théoriques, mais qu'ils devaient être vendus sur les avantages spécifiques à eux, alors voici les points que j'ai utilisés (avec succès):

  • Ils gagnent du temps lors des tests négatifs, où vous gérez les entrées inattendues (pointeurs NULL, valeurs hors limites, etc.), comme vous pouvez le faire en un seul processus.
  • Ils fournissent une rétroaction immédiate au moment de la compilation en ce qui concerne la norme des changements.
  • Ils sont utiles pour tester les représentations de données internes qui peuvent ne pas être exposées pendant l'exécution normale.

et le grand ...

  • Vous n'avez peut-être pas besoin de tests unitaires, mais quand quelqu'un d'autre intervient et modifie le code sans une compréhension complète, il peut attraper beaucoup des erreurs stupides qu'ils pourraient commettre.

Je n'ai vu cela dans aucune des autres réponses, mais une chose que j'ai remarquée est que je pourrais déboguer beaucoup plus rapidement . Vous n'avez pas besoin de naviguer dans votre application avec la bonne séquence d'étapes pour obtenir le code de votre solution, seulement pour constater que vous avez fait une erreur booléenne et que vous devez tout recommencer. Avec un test unitaire, vous pouvez simplement entrer directement dans le code que vous déboguez.



Je travaille en tant qu'ingénieur de maintenance d'une base de code mal documentée, terrible et grande. Je souhaite que les personnes qui ont écrit le code aient écrit les tests unitaires pour cela.
Chaque fois que je fais un changement et que je mets à jour le code de production, j'ai peur d'introduire un bug pour ne pas avoir pris en compte certaines conditions.
S'ils écrivaient le test, il serait plus facile et plus rapide d'apporter des modifications à la base de code (en même temps, la base du code serait dans un meilleur état).

Je pense que les tests unitaires s'avèrent très utiles lors de l'écriture d'api ou de frameworks qui doivent durer de nombreuses années et être utilisés / modifiés / développés par des personnes autres que les codeurs d'origine.


La meilleure façon de convaincre ... de trouver un bug, d'écrire un test unitaire, de corriger le bug.

Ce bug particulier est peu susceptible d'apparaître à nouveau, et vous pouvez le prouver avec votre test.

Si vous le faites assez, les autres vont vite se faire remarquer.


Les tests unitaires aident beaucoup dans les projets qui sont plus grands que tout développeur peut tenir dans leur tête. Ils vous permettent d'exécuter la suite de tests unitaires avant de vous enregistrer et de découvrir si vous avez cassé quelque chose. Cela réduit beaucoup les cas où vous devez vous asseoir et vous tourner les pouces en attendant que quelqu'un d'autre répare un bogue enregistré, ou se rendre à la tâche fastidieuse de revenir sur sa modification pour que vous puissiez travailler. Il est également extrêmement précieux dans le refactoring, donc vous pouvez être sûr que le code refactorisé passe tous les tests que le code original a fait.


Les tests unitaires sont également particulièrement utiles lorsqu'il s'agit de refactoriser ou de réécrire un morceau d'un code. Si vous avez une bonne couverture des tests unitaires, vous pouvez refactoriser en toute confiance. Sans tests unitaires, il est souvent difficile de s'assurer que vous n'avez rien cassé.


Les tests unitaires valent bien l'investissement initial. Depuis que j'ai commencé à utiliser les tests unitaires il y a quelques années, j'ai trouvé de réels avantages:

  • les tests de régression éliminent la crainte de modifier le code (il n'y a rien de tel que le fait de voir le code fonctionner ou d'exploser chaque fois qu'un changement est fait)
  • exemples de code exécutable pour les autres membres de l'équipe (et vous-même dans six mois)
  • refactoring impitoyable - c'est incroyablement enrichissant, essayez-le!

Les extraits de code peuvent être d'une grande aide pour réduire les frais généraux liés à la création de tests. Il n'est pas difficile de créer des extraits qui permettent la création d'un contour de classe et d'un appareil de test d'unité associé en quelques secondes.


Oui - Les tests unitaires en valent vraiment la peine, mais vous devriez savoir que ce n'est pas une solution miracle. Le test unitaire est un travail et vous devrez travailler pour garder le test à jour et pertinent en tant que changement de code mais la valeur offerte vaut l'effort que vous avez à mettre. La capacité à refactoriser en toute impunité est un énorme avantage car vous pouvez toujours valider la fonctionnalité en exécutant vos tests après tout code de modification. L'astuce consiste à ne pas trop s'accrocher à l'unité de travail que vous testez ou à la façon dont vous établissez les exigences d'un test d'échafaudage et quand un test unitaire est vraiment un test fonctionnel, etc. Les gens se disputent pendant des heures. à la fin et la réalité est que tout test que vous faites en tant que votre code d'écriture est mieux que de ne pas le faire. L'autre axiome concerne la qualité et non la quantité - j'ai vu des bases de code avec des tests de 1000 qui sont essentiellement dénués de sens car le reste ne teste pas vraiment quelque chose d'utile ou de domaine spécifique comme les règles métier, etc. J'ai également vu des bases de code avec une couverture de code de 30% mais les tests étaient pertinents, significatifs et vraiment géniaux car ils ont testé la fonctionnalité de base du code pour lequel il a été écrit et ont expliqué comment le code devrait être utilisé.

L'un de mes trucs favoris lors de l'exploration de nouveaux frameworks ou de nouvelles bases de code consiste à écrire des tests unitaires pour 'it' afin de découvrir comment les choses fonctionnent. C'est un excellent moyen d'en apprendre plus sur quelque chose de nouveau au lieu de lire un doc sec :)


Pendant des années, j'ai essayé de convaincre les gens qu'ils devaient écrire un test d'unité pour leur code. Qu'ils aient écrit les tests en premier (comme dans TDD) ou après avoir codé la fonctionnalité, j'ai toujours essayé de leur expliquer tous les avantages d'avoir des tests unitaires pour le code. Presque personne n'était en désaccord avec moi. Vous ne pouvez pas être en désaccord avec quelque chose qui est évident, et toute personne intelligente verra les avantages du test unitaire et du TDD.

Le problème avec les tests unitaires est qu'il nécessite un changement de comportement, et il est très difficile de changer le comportement des gens. Avec des mots, vous obtiendrez beaucoup de gens d'accord avec vous, mais vous ne verrez pas beaucoup de changements dans la façon dont ils font les choses.

Vous devez convaincre les gens en faisant. Votre succès personnel attirera plus de gens que tous les arguments que vous pourriez avoir. S'ils voient que vous ne parlez pas seulement du test unitaire ou du TDD, mais que vous faites ce que vous prêchez, et que vous réussissez, les gens vont essayer de vous imiter.

Vous devez également assumer un rôle de chef de file, car personne n'écrit de test unitaire correctement la première fois. Vous devrez peut-être les entraîner sur la façon de le faire, leur montrer le chemin et les outils à leur disposition. Aidez-les pendant qu'ils écrivent leurs premiers tests, passez en revue les tests qu'ils rédigent eux-mêmes et montrez-leur les trucs, les idiomes et les modèles que vous avez appris grâce à vos propres expériences. Après un certain temps, ils commenceront à voir les avantages par eux-mêmes, et ils changeront leur comportement pour incorporer des tests unitaires ou TDD dans leur boîte à outils.

Les changements n'auront pas lieu pendant la nuit, mais avec un peu de patience, vous pourrez atteindre votre objectif.


Si votre base de code existante ne se prête pas à des tests unitaires et qu'elle est déjà en production, vous risquez de créer plus de problèmes que vous n'en résolvez en essayant de refactoriser tout votre code pour qu'il soit testable à l'unité.

Vous feriez peut-être mieux de vous concentrer sur l'amélioration de vos tests d'intégration. Il y a beaucoup de code qui est simplement plus simple à écrire sans un test unitaire, et si un QA peut valider la fonctionnalité par rapport à un document d'exigences, alors vous avez terminé. Expédier.

L'exemple classique de ceci dans mon esprit est un SqlDataReader incorporé dans une page d'ASPX liée à un GridView. Le code est tout dans le fichier ASPX. Le SQL est dans une procédure stockée. Qu'est-ce que vous testez l'unité? Si la page fait ce qu'elle est censée faire, devriez-vous vraiment la reconcevoir en plusieurs couches pour que vous ayez quelque chose à automatiser?


Si vous utilisez NUnit, une démo simple mais efficace consiste à exécuter les propres suites de tests de NUnit devant eux. Voir une vraie suite de tests donner une base de code à un exercice vaut mille mots ...


Une chose que personne n'a encore mentionné est l'engagement de tous les développeurs à exécuter et à mettre à jour tout test automatisé existant. Les tests automatisés auxquels vous revenez et que vous trouvez cassés en raison d'un nouveau développement perdent beaucoup de valeur et rendent les tests automatisés vraiment douloureux. La plupart de ces tests n'indiqueront pas de bugs puisque le développeur a testé le code manuellement, donc le temps passé à les mettre à jour n'est que gaspillage.

Convaincre les sceptiques de ne pas détruire le travail que les autres font sur les tests unitaires est beaucoup plus important pour obtenir la valeur des tests et pourrait être plus facile.

Passer des heures à mettre à jour les tests qui ont été interrompus à cause de nouvelles fonctionnalités chaque fois que vous mettez à jour depuis le dépôt n'est ni productif ni amusant.


Une partie importante du développement piloté par les tests qui est souvent passé sous silence est l'écriture de code testable. Cela semble être une sorte de compromis au début, mais vous découvrirez que le code testable est finalement modulaire, maintenable et lisible. Si vous avez encore besoin d'aide pour convaincre les gens, this s'agit d'une belle présentation simple sur les avantages des tests unitaires.


[J'ai un point à faire que je ne peux pas voir ci-dessus]

"Tout le monde les tests unitaires, ils ne le réalisent pas nécessairement - FACT"

Pensez-y, vous écrivez une fonction pour peut-être analyser une chaîne et supprimer les caractères de nouvelle ligne. En tant que développeur débutant, vous pouvez soit lancer quelques cas à partir de la ligne de commande en l'implémentant dans Main () ou vous associez un frontal visuel avec un bouton, associez votre fonction à quelques zones de texte et un bouton et voyez ce qui se produit.

C'est un test unitaire - basique et mal mis en place mais vous testez le code pour quelques cas.

Vous écrivez quelque chose de plus complexe. Il lance des erreurs lorsque vous lancez quelques cas (tests unitaires) et vous déboguez dans le code et tracez cependant. Vous regardez les valeurs au fur et à mesure et vous décidez si elles ont raison ou tort. C'est un test unitaire dans une certaine mesure.

Les tests unitaires ici prennent vraiment ce comportement, en le formalisant dans un modèle structuré et en le sauvegardant afin que vous puissiez facilement relancer ces tests. Si vous écrivez un test élémentaire "correct" plutôt que de le tester manuellement, cela prend le même temps, ou peut-être moins, et vous pouvez le répéter encore et encore.


Les tests unitaires, c'est un peu comme aller au gym. Vous savez que c'est bon pour vous, tous les arguments ont un sens, alors vous commencez à vous entraîner. Il y a une première poussée, ce qui est génial, mais après quelques jours, vous commencez à vous demander si cela en vaut la peine. Vous prenez une heure de votre journée pour changer de vêtements et courir sur une roue de hamster et vous n'êtes pas sûr de vraiment gagner autre chose que des jambes et des bras endoloris.

Puis, après peut-être une ou deux semaines, tout comme la douleur disparaît, une grande date limite approche. Vous devez passer chaque heure éveillée à essayer de faire un travail «utile», afin de supprimer des choses superflues, comme aller à la gym. Vous tombez en dehors de l'habitude, et au moment où Big Deadline est terminée, vous êtes de retour à la case départ. Si vous parvenez à revenir à la salle de gym du tout, vous vous sentez aussi douloureux que vous étiez la première fois que vous êtes allé.

Vous lisez, pour voir si vous faites quelque chose de mal. Vous commencez à ressentir un peu de dépit irrationnel envers tous ceux qui sont en forme, des gens heureux vantant les vertus de l'exercice. Vous réalisez que vous n'avez pas beaucoup en commun. Ils n'ont pas à conduire 15 minutes pour aller à la gym; il y en a un dans leur immeuble. Ils n'ont pas à discuter avec qui que ce soit des avantages de l'exercice; c'est juste quelque chose que tout le monde fait et accepte comme important. Lorsqu'une grande date limite approche, on ne leur dit pas que l'exercice n'est pas plus nécessaire que votre patron vous demanderait d'arrêter de manger.

Donc, pour répondre à votre question, les tests unitaires en valent généralement la peine, mais l'effort requis ne sera pas le même pour tout le monde. Les tests unitaires peuvent exiger beaucoup d'efforts si vous traitez avec du code spaghetti dans une entreprise qui n'apprécie pas vraiment la qualité du code. (Beaucoup de gestionnaires vont chanter les louanges d'Unit Testing, mais cela ne veut pas dire qu'ils vont le supporter quand ça compte.)

Si vous essayez d'introduire le test unitaire dans votre travail et que vous ne voyez pas tous les rayons de soleil et les arcs-en-ciel auxquels vous êtes habitués, ne vous blâmez pas. Vous pourriez avoir besoin de trouver un nouveau travail pour vraiment faire fonctionner les tests unitaires pour vous.







unit-testing