unit-testing - intégration - test unitaire php




Les tests unitaires peuvent-ils être ajoutés avec succès dans un projet de production existant? Si oui, comment et vaut-il la peine? (16)

  • Cela vaut-il la peine d'investir dans une solution existante en production?

Oui!

  • Vaut-il mieux ignorer les tests pour ce projet et l'ajouter dans une future réécriture possible?

Non!

  • Qu'est-ce qui sera le plus bénéfique? passer quelques semaines à ajouter des tests ou quelques semaines à ajouter des fonctionnalités?

L'ajout de tests (en particulier les tests automatisés) facilite grandement le fonctionnement du projet dans le futur, et il est beaucoup moins probable que vous envoyiez des problèmes stupides à l'utilisateur.

Les tests à mettre en a priori sont ceux qui vérifient si ce que vous croyez que l'interface publique de votre code (et chaque module qui s'y trouve) fonctionne comme vous le pensez. Si vous le pouvez, essayez d'induire aussi chaque mode de défaillance isolé que vos modules de code devraient avoir (notez que cela peut être non trivial, et vous devriez faire attention à ne pas vérifier trop attentivement comment les choses échouent, par exemple, vous ne voulez pas vraiment pour faire des choses comme compter le nombre de messages de journal produits en cas d'échec, puisque la vérification qu'il est connecté à tout est suffisant).

Ensuite, mettez un test pour chaque bogue actuel dans votre base de données de bogues qui induit exactement le bogue et qui passera quand le bogue sera corrigé. Puis corrigez ces bugs! :-)

Cela prend du temps avant d'ajouter des tests, mais vous êtes remboursé plusieurs fois à l'arrière car votre code finit par être de meilleure qualité. Cela compte énormément lorsque vous essayez d'expédier une nouvelle version ou d'effectuer une maintenance.

J'envisage fortement d'ajouter des tests unitaires à un projet existant en production. Cela a commencé il y a 18 mois avant que je puisse vraiment voir un avantage de TDD (face palm) , alors maintenant c'est une solution assez grande avec un certain nombre de projets et je n'ai pas la moindre idée de l'endroit où commencer les tests unitaires. Ce qui me fait penser c'est que parfois un vieux bug semble refaire surface, ou qu'un bug est enregistré comme corrigé sans vraiment être corrigé. Les tests unitaires réduiraient ou empêcheraient ces problèmes.

En lisant similar questions similar sur SO, j'ai vu des recommandations telles que le démarrage du bug tracker et l'écriture d'un cas de test pour chaque bug afin d'éviter la régression. Cependant, je crains que je finisse par manquer la grande image et finisse par manquer des tests fondamentaux qui auraient été inclus si j'avais utilisé TDD dès le départ.

Existe-t-il des processus / étapes à suivre pour s'assurer que les solutions existantes sont correctement testées et ne sont pas simplement incrustées? Comment puis-je assurer que les tests sont de bonne qualité et ne sont pas seulement un cas de test est mieux que pas de tests .

Donc je suppose que ce que je demande aussi est;

  • Cela vaut-il la peine d'investir dans une solution existante en production?
  • Vaut-il mieux ignorer les tests pour ce projet et l'ajouter dans une future réécriture possible?
  • Qu'est-ce qui sera le plus bénéfique? passer quelques semaines à ajouter des tests ou quelques semaines à ajouter des fonctionnalités?

(Évidemment, la réponse au troisième point dépend entièrement de si vous parlez à la direction ou à un développeur)

Raison de la générosité

Ajouter une prime pour essayer d'attirer un plus large éventail de réponses qui non seulement confirme mon soupçon actuel que c'est une bonne chose à faire, mais aussi de bonnes raisons.

Je vise à écrire cette question plus tard avec des avantages et des inconvénients pour essayer de montrer à la direction qu'il vaut la peine de passer les heures de travail sur le déplacement du développement futur du produit à TDD. Je veux aborder ce défi et développer mon raisonnement sans mon propre point de vue biaisé.


Ça dépend...
C'est génial d'avoir des tests unitaires, mais vous devez considérer qui sont vos utilisateurs et ce qu'ils sont prêts à tolérer afin d'obtenir un produit sans bug. Inévitablement, en refactorisant votre code qui n'a pas de tests unitaires à l'heure actuelle, vous allez introduire des bugs et beaucoup d'utilisateurs auront du mal à comprendre que vous rendiez le produit temporairement plus défectueux pour le rendre moins défectueux à long terme. En fin de compte, ce sont les utilisateurs qui auront le dernier mot ...


Il y a tellement de bonnes réponses que je ne répéterai pas leur contenu. J'ai vérifié votre profil et il semble que vous soyez développeur C # .NET. Pour cette raison, j'ajoute une référence au projet Microsoft PEX et Moles qui peut vous aider à générer automatiquement des tests unitaires pour le code existant. Je sais que l'autogénération n'est pas le meilleur moyen mais au moins c'est la façon de commencer. Consultez cet article très intéressant du magazine MSDN sur l'utilisation de PEX pour le code existant .


J'ai introduit des tests unitaires pour coder les bases qui ne l'avaient pas auparavant. Le dernier gros projet dans lequel j'ai travaillé, le produit était déjà en production avec zéro tests unitaires quand je suis arrivé à l'équipe. Quand je suis parti - 2 ans plus tard - nous avions plus de 4500 tests générant environ 33% de couverture de code dans une base de code avec 230 000 + production LOC (application Win-Forms financière en temps réel). Cela peut sembler faible, mais le résultat a été une amélioration significative de la qualité du code et du taux de défectuosité, ainsi qu'une amélioration du moral et de la rentabilité.

Cela peut être fait quand vous avez à la fois une compréhension précise et un engagement des parties impliquées.

Tout d'abord, il est important de comprendre que les tests unitaires sont une compétence en soi. Vous pouvez être un programmeur très productif selon des normes «conventionnelles» et vous avez toujours du mal à écrire des tests unitaires d'une manière qui évolue dans un projet plus vaste.

Aussi, et spécifiquement pour votre situation, ajouter des tests unitaires à une base de code existante qui n'a pas de tests est également une compétence spécialisée en soi. À moins que vous ou quelqu'un de votre équipe ait une expérience réussie avec l'introduction de tests unitaires à une base de code existante, je dirais que lire le livre de Feather est une exigence (non facultative ou fortement recommandée).

Faire la transition à l'unité de test de votre code est un investissement dans les personnes et les compétences tout autant que dans la qualité de la base de code. Comprendre cela est très important en termes d'état d'esprit et de gestion des attentes.

Maintenant, pour vos commentaires et questions:

Cependant, je crains que je finisse par manquer la grande image et finisse par manquer des tests fondamentaux qui auraient été inclus si j'avais utilisé TDD dès le départ.

Réponse courte: Oui, vous manquerez des tests et oui, ils pourraient ne pas ressembler à ce qu'ils auraient dans une situation de terrain vert.

Réponse de niveau plus profond est la suivante: Cela n'a pas d'importance. Vous commencez avec aucun test. Commencez à ajouter des tests et refactorisez-les au fur et à mesure. À mesure que les niveaux de compétence s'améliorent, commencez à élever la barre pour tout nouveau code ajouté à votre projet. Continuez à améliorer etc ...

Maintenant, en lisant entre les lignes ici j'ai l'impression que cela vient de l'état d'esprit de "la perfection comme une excuse pour ne pas agir". Un meilleur état d'esprit est de se concentrer sur la confiance en soi. Comme vous ne savez peut-être pas encore comment faire, vous comprendrez comment vous allez et remplissez les espaces vides. Par conséquent, il n'y a aucune raison de s'inquiéter.

Encore une fois, c'est une compétence. Vous ne pouvez pas passer de tests zéro à la perfection TDD dans une approche de livre de cuisine «processus» ou «étape par étape» de manière linéaire. Ce sera un processus. Vos attentes doivent être de faire des progrès graduels et progressifs et des améliorations. Il n'y a pas de pilule magique.

Les bonnes nouvelles sont que, au fil des mois (et même des années), votre code va progressivement commencer à devenir un code «correct» bien factorisé et bien testé.

Comme une note de côté. Vous constaterez que le principal obstacle à l'introduction de tests unitaires dans une ancienne base de code est le manque de cohésion et les dépendances excessives. Vous allez donc probablement trouver que la compétence la plus importante deviendra comment briser les dépendances existantes et le code de découplage, plutôt que d'écrire les tests unitaires eux-mêmes.

Existe-t-il des processus / étapes à suivre pour s'assurer que les solutions existantes sont correctement testées et ne sont pas simplement incrustées?

À moins que vous ne l'ayez déjà, configurez un serveur de génération et configurez une génération d'intégration continue qui s'exécute à chaque contrôle, y compris tous les tests unitaires avec une couverture de code.

Entraînez votre peuple.

Commencez quelque part et commencez à ajouter des tests pendant que vous progressez du point de vue du client (voir ci-dessous).

Utilisez la couverture de code comme référence pour déterminer la quantité de votre base de code de production testée.

Le temps de construction doit toujours être RAPIDE. Si votre temps de construction est lent, vos compétences en tests unitaires sont à la traîne. Trouvez les tests lents et améliorez-les (découpler le code de production et tester de manière isolée). Bien écrit, vous devriez facilement avoir plusieurs milliers de tests unitaires et encore terminer une compilation en moins de 10 minutes (~ 1-ms / test est un bon guide mais très approximatif, quelques exceptions peuvent s'appliquer comme le code en utilisant la réflexion etc. ).

Inspecter et adapter.

Comment puis-je assurer que les tests sont de bonne qualité et ne sont pas seulement un cas de test est mieux que pas de tests.

Votre propre jugement doit être votre principale source de réalité. Il n'y a pas de mesure pouvant remplacer la compétence.

Si vous n'avez pas cette expérience ou ce jugement, pensez à embaucher quelqu'un qui le fait.

Deux indicateurs secondaires approximatifs sont la couverture totale du code et la vitesse de construction.

Cela vaut-il la peine d'investir dans une solution existante en production?

Oui. La grande majorité de l'argent dépensé pour un système ou une solution personnalisée est dépensée après sa mise en production. Et investir dans la qualité, les personnes et les compétences ne devrait jamais être démodé.

Vaut-il mieux ignorer les tests pour ce projet et l'ajouter dans une future réécriture possible?

Vous devez prendre en considération, non seulement l'investissement dans les personnes et les compétences, mais surtout le coût total de possession et la durée de vie prévue du système.

Ma réponse personnelle serait «oui bien sûr» dans la majorité des cas parce que je sais que c'est tellement mieux, mais je reconnais qu'il pourrait y avoir des exceptions.

Qu'est-ce qui sera le plus bénéfique? passer quelques semaines à ajouter des tests ou quelques semaines à ajouter des fonctionnalités?

Ni. Votre approche devrait être d'ajouter des tests à votre base de code PENDANT que vous progressez en termes de fonctionnalité.

Encore une fois, c'est un investissement dans les gens, les compétences et la qualité de la base de code et en tant que tel, il faudra du temps. Les membres de l'équipe doivent apprendre à rompre les dépendances, écrire des tests unitaires, apprendre de nouveaux habbits, améliorer la discipline et la qualité, mieux concevoir les logiciels, etc. Il est important de comprendre que lorsque vous commencez à ajouter des tests, les membres de votre équipe ne le font probablement pas. avoir ces compétences encore au niveau qu'ils doivent être pour que cette approche soit couronnée de succès, alors arrêter de progresser pour passer tout le temps nécessaire pour ajouter beaucoup de tests ne fonctionnera tout simplement pas.

En outre, l'ajout de tests unitaires à une base de code existante de toute taille de projet importante est une vaste entreprise qui nécessite engagement et persistance. Vous ne pouvez pas changer quelque chose de fondamental, attendre beaucoup d'apprentissage sur le chemin et demander à votre sponsor de ne pas s'attendre à un retour sur investissement en arrêtant le flux de la valeur commerciale. Cela ne va pas voler, et franchement cela ne devrait pas.

Troisièmement, vous voulez inculquer de bonnes valeurs métier dans votre équipe. La qualité ne vient jamais au détriment du client et vous ne pouvez pas aller vite sans qualité. De plus, le client vit dans un monde en évolution et votre travail consiste à lui faciliter l'adaptation. L'alignement du client nécessite à la fois la qualité et le flux de la valeur métier.

Ce que vous faites, c'est rembourser la dette technique. Et vous le faites tout en servant toujours vos besoins en constante évolution de vos clients. Au fur et à mesure que la dette est remboursée, la situation s'améliore et il est plus facile de mieux servir le client et d'offrir plus de valeur. Etc. Cet élan positif est ce que vous devriez viser parce qu'il souligne les principes du rythme soutenable et maintiendra et améliorera la morale - tant pour votre équipe de développement, votre client et vos dépositaires.

J'espère que cela pourra aider


Je suggère de lire un article brillant par un ingénieur TopTal, qui explique commencer à ajouter des tests: il contient beaucoup de maths, mais l'idée de base est:

1) Mesurez le couplage afférent (CA) de votre code (à quel point une classe est utilisée par d'autres classes, ce qui signifie que la rupture causerait des dommages étendus)

2) Mesurez la complexité cyclomatique de votre code (CC) (complexité plus élevée = changement de rupture plus important)

Vous devez identifier les classes ayant un CA et un CC élevés, c'est-à-dire avoir une fonction f (CA, CC) et les classes ayant les plus petites différences entre les deux métriques devraient recevoir la plus haute priorité pour la couverture de test.

Pourquoi? Parce qu'une CA élevée mais des classes CC très faibles sont très importantes mais peu susceptibles de se casser. D'un autre côté, un CA faible mais un CC élevé risquent de se casser, mais causeront moins de dégâts. Donc, vous voulez équilibrer.


Je suis d'accord avec ce que la plupart des autres ont dit. L'ajout de tests au code existant est précieux. Je ne suis jamais en désaccord avec ce point, mais j'aimerais ajouter une mise en garde.

Bien que l'ajout de tests au code existant soit précieux, cela a un coût. Cela vient au prix de ne pas construire de nouvelles fonctionnalités. La façon dont ces deux choses s'équilibrent dépend entièrement du projet, et il y a un certain nombre de variables.

  • Combien de temps cela vous prendra-t-il pour tester tout ce code? Journées? Semaines? Mois? Années?
  • Pour qui écrivez-vous ce code? Payer les clients? Un enseignant? Un projet open source?
  • À quoi ressemble ton horaire? Avez-vous des échéances difficiles à respecter? Avez-vous des délais?

Encore une fois, permettez-moi de souligner que les tests sont utiles et que vous devriez travailler à mettre votre ancien code à l'épreuve. C'est vraiment plus une question de comment vous l'approchez. Si vous pouvez vous permettre de tout laisser tomber et de tester tout votre ancien code, faites-le. Si ce n'est pas réaliste, voici ce que vous devriez faire à tout le moins

  • Tout nouveau code que vous écrivez doit être complètement sous test unitaire
  • Tout ancien code que vous touchez (correction de bogue, extension, etc.) doit être mis sous test unitaire

En outre, ce n'est pas une proposition tout ou rien. Si vous avez une équipe de quatre personnes, par exemple, et que vous pouvez respecter vos délais en mettant une ou deux personnes à l'essai, il faut le faire.

Modifier:

Je vise à écrire cette question plus tard avec des avantages et des inconvénients pour essayer de montrer à la direction qu'il vaut la peine de passer les heures de travail sur le déplacement du développement futur du produit à TDD.

C'est comme demander "Quels sont les avantages et les inconvénients d'utiliser le contrôle de la source?" ou "Quels sont les avantages et les inconvénients d'interroger les gens avant de les embaucher?" ou "Quels sont les avantages et les inconvénients de respirer?"

Parfois, il n'y a qu'un côté de l'argument. Vous devez avoir des tests automatisés d'une certaine forme pour n'importe quel projet de n'importe quelle complexité. Non, les tests ne s'écrivent pas eux-mêmes, et, oui, il faudra un peu plus de temps pour sortir les choses. Mais à long terme, cela prendra plus de temps et coûtera plus d'argent pour corriger les bugs après le fait que d'écrire des tests à l'avance. Période. C'est tout ce qu'on peut en dire.


Je vais ajouter ma voix et dire oui, c'est toujours utile!

Il y a cependant quelques distinctions que vous devriez garder à l'esprit: black-box vs white-box, et unit vs functional. Puisque les définitions varient, voici ce que je veux dire par:

  • Black-box = tests qui sont écrits sans connaissance particulière de l'implémentation, typiquement en piquant autour des cas limites pour s'assurer que les choses se passent comme un utilisateur naïf l'attendrait.
  • White-box = tests écrits avec la connaissance de l'implémentation, qui essaient souvent d'exercer des points d'échecs bien connus.
  • Tests unitaires = tests d'unités individuelles (fonctions, modules séparables, etc.). Par exemple: assurez-vous que votre classe de tableau fonctionne comme prévu, et que votre fonction de comparaison de chaînes renvoie les résultats attendus pour un large éventail d'entrées.
  • Tests fonctionnels = tests de l'ensemble du système en une fois. Ces tests exerceront une grande partie du système tout à la fois. Par exemple: init, ouvrez une connexion, faites des choses du monde réel, fermez, terminez. J'aime faire une distinction entre ceux-ci et les tests unitaires, car ils servent un objectif différent.

Lorsque j'ai ajouté des tests à un produit d'expédition en fin de partie, j'ai constaté que je tirais le meilleur parti de la boîte blanche et des tests fonctionnels . Si une partie du code que vous connaissez est particulièrement fragile, écrivez des tests en blanc pour couvrir les cas problématiques afin de vous assurer qu'il ne se casse pas deux fois de la même manière. De même, les tests fonctionnels de l'ensemble du système constituent une vérification de santé utile qui vous aide à vous assurer de ne jamais casser les 10 cas d'utilisation les plus courants.

Les tests en boîte noire et en unités de petites unités sont également utiles, mais si votre temps est limité, il est préférable de les ajouter tôt. Au moment où vous expédiez, vous avez généralement trouvé (à la dure) la majorité des cas limites et des problèmes que ces tests auraient trouvé.

Comme les autres, je vais aussi vous rappeler les deux choses les plus importantes à propos de TDD:

  1. Créer des tests est un travail continu. Ça ne s'arrête jamais. Vous devriez essayer d'ajouter de nouveaux tests chaque fois que vous écrivez un nouveau code, ou modifiez un code existant.
  2. Votre suite de tests n'est jamais infaillible! Ne laissez pas le fait que vous avez des tests vous endormir dans un faux sentiment de sécurité. Ce n'est pas parce qu'il réussit la suite de tests qu'il fonctionne correctement, ou que vous n'avez pas introduit une régression subtile des performances, etc.

Je voudrais commencer cette réponse en disant que les tests unitaires sont vraiment importants car ils vous aideront à arrêter les bugs avant qu'ils ne se fassent en production.

Identifier les zones projets / modules où les bogues ont été réintroduits. Commencer avec ces projets pour écrire des tests. Il est parfaitement logique d'écrire des tests pour de nouvelles fonctionnalités et pour corriger les bogues.

Cela vaut-il la peine d'investir dans une solution existante en production?

Oui. Vous verrez l'effet des bugs et la maintenance devient plus facile

Vaut-il mieux ignorer les tests pour ce projet et l'ajouter dans une future réécriture possible?

Je recommanderais de commencer si maintenant.

Qu'est-ce qui sera le plus bénéfique? passer quelques semaines à ajouter des tests ou quelques semaines à ajouter des fonctionnalités?

Vous posez la mauvaise question. Définitivement, la fonctionnalité est plus importante que toute autre chose. Mais, plutôt vous devriez demander si passer quelques semaines en ajoutant le test rendra mon système plus stable. Est-ce que cela aidera mon utilisateur final? Cela aidera-t-il un nouveau développeur de l'équipe à comprendre le projet et à s'assurer qu'il / elle n'introduit pas de bogue en raison d'un manque de compréhension de l'impact global d'un changement.


Le problème avec les tests unitaires de rattrapage est que vous réaliserez que vous n'avez pas pensé à injecter une dépendance ici ou à utiliser une interface là-bas, et avant longtemps vous allez réécrire le composant entier. Si vous avez le temps de le faire, vous allez construire un beau filet de sécurité, mais vous pourriez avoir introduit des bugs subtils en cours de route.

J'ai été impliqué dans de nombreux projets qui nécessitaient des tests unitaires dès le premier jour, et il n'y a pas de moyen facile de les intégrer, à moins d'une réécriture complète, qui ne peut généralement pas être justifiée quand le code fonctionne déjà. Récemment, j'ai eu recours à l'écriture de scripts PowerShell qui exercent le code de manière à reproduire un défaut dès qu'il est levé et à conserver ces scripts comme une suite de tests de régression pour d'autres changements sur la ligne. De cette façon, vous pouvez au moins commencer à construire des tests pour l'application sans trop la modifier, cependant, ils ressemblent plus à des tests de régression de bout en bout qu'à des tests unitaires appropriés.


Lorsque nous avons commencé à ajouter des tests, il s'agissait d'une base de code d'environ dix millions d'années, avec beaucoup trop de logique dans l'interface utilisateur et dans le code de reporting.

L'une des premières choses que nous avons faites (après la mise en place d'un serveur de build continu) était d'ajouter des tests de régression. Ce sont des tests de bout en bout.

  • Chaque suite de tests commence par initialiser la base de données à un état connu. Nous avons en fait des dizaines de jeux de données de régression que nous conservons dans Subversion (dans un référentiel séparé de notre code, en raison de la taille pure). FixtureSetUp de chaque test copie l'un de ces jeux de données de régression dans une base de données temporaire, puis s'exécute à partir de là.
  • La configuration du banc de test exécute alors un processus dont les résultats nous intéressent. (Cette étape est facultative - certains tests de régression n'existent que pour tester les rapports.)
  • Ensuite, chaque test exécute un rapport, génère le rapport dans un fichier .csv et compare le contenu de ce fichier .csv à un instantané enregistré. Ces fichiers .csv instantanés sont stockés dans Subversion à côté de chaque jeu de données de régression. Si la sortie du rapport ne correspond pas à l'instantané enregistré, le test échoue.

Le but des tests de régression est de vous dire si quelque chose change. Cela signifie qu'ils échouent si vous avez cassé quelque chose, mais ils échouent également si vous avez modifié quelque chose volontairement (dans ce cas, le correctif consiste à mettre à jour le fichier d'instantané). Vous ne savez pas que les fichiers instantanés sont même corrects - il peut y avoir des bogues dans le système (et lorsque vous corrigez ces bogues, les tests de régression échouent).

Néanmoins, les tests de régression ont été une énorme victoire pour nous. À peu près tout dans notre système a un rapport, donc en passant quelques semaines à tester les rapports, nous avons pu obtenir un certain niveau de couverture sur une grande partie de notre base de code. La rédaction des tests unitaires équivalents aurait pris des mois ou des années. (Les tests unitaires nous auraient donné une bien meilleure couverture et auraient été beaucoup moins fragiles, mais je préférerais avoir quelque chose maintenant, plutôt que d'attendre des années pour la perfection.)

Puis nous sommes retournés et avons commencé à ajouter des tests unitaires lorsque nous avons corrigé des bogues, ou ajouté des améliorations, ou nécessaire pour comprendre du code. Les tests de régression ne suppriment en aucun cas le besoin de tests unitaires; Ce n'est qu'un filet de sécurité de premier niveau, ce qui vous permet d'obtenir rapidement une couverture de test. Ensuite, vous pouvez commencer à refactoring pour casser les dépendances, de sorte que vous pouvez ajouter des tests unitaires; et les tests de régression vous donnent un niveau de confiance que votre refactoring ne brise rien.

Les tests de régression ont des problèmes: ils sont lents et il y a trop de raisons pour qu'ils puissent se casser. Mais au moins pour nous, ils en valaient vraiment la peine. Ils ont attrapé d'innombrables bogues au cours des cinq dernières années, et ils les attrapent en quelques heures, plutôt que d'attendre un cycle d'AQ. Nous avons toujours ces tests de régression originaux, répartis sur sept machines de construction continue différentes (séparées de celles qui exécutent les tests unitaires rapides), et nous y ajoutons même de temps en temps, parce que nous avons toujours autant de code que nos 6000 + les tests unitaires ne couvrent pas.


Oui. Ajouter des tests

Aller vers une approche plus TDD permettra de mieux informer vos efforts pour ajouter de nouvelles fonctionnalités et rendre les tests de régression beaucoup plus facile. Vérifiez-le!


Si j'étais à votre place, je prendrais probablement une approche de l'extérieur, en commençant par des tests fonctionnels qui exercent tout le système. Je voudrais essayer de documenter les exigences du système en utilisant un langage de spécification BDD comme RSpec, puis écrire des tests pour vérifier ces exigences en automatisant l'interface utilisateur.

Ensuite, je ferais du développement piloté par défaut pour les bogues nouvellement découverts, j'écrirais des tests unitaires pour reproduire les problèmes, et je travaillerais sur les bogues jusqu'à ce que les tests soient passés.

Pour les nouvelles fonctionnalités, je voudrais rester avec l'approche extérieure: Commencer avec les fonctionnalités documentées dans RSpec et vérifiées en automatisant l'interface utilisateur (qui échouera bien sûr au début), puis ajouter plus de tests unitaires finement granulaires que l'implémentation se déplace le long.

Je ne suis pas un expert en la matière, mais je peux vous dire que le BDD via un test automatisé de l'interface utilisateur n'est pas facile, mais je pense que cela en vaut la peine et que cela vous apportera probablement le plus d'avantages.


Vous ne mentionnez pas le langage d'implémentation, mais si vous utilisez Java, vous pouvez essayer cette approche:

  1. Dans un arbre source séparé, construisez des tests de régression ou de «fumée», en utilisant un outil pour les générer, ce qui pourrait vous rapporter jusqu'à 80% de couverture. Ces tests exécutent tous les chemins logiques de code et vérifient à partir de ce point que le code fait exactement ce qu'il fait actuellement (même si un bogue est présent). Cela vous donne un filet de sécurité contre tout changement involontaire de comportement lors de la refactorisation nécessaire pour rendre le code facilement testable à la main.

  2. Pour chaque bogue que vous corrigez, ou que vous ajoutez à partir de maintenant, utilisez une approche TDD pour vous assurer que le nouveau code est conçu pour être testable et placez ces tests dans une arborescence source de test normale.

  3. Le code existant devra aussi probablement être modifié ou refactorisé pour le rendre testable dans le cadre de l'ajout de nouvelles fonctionnalités; vos tests de fumée vous donneront un filet de sécurité contre les régressions ou les changements de comportement subtils par inadvertance.

  4. Lorsque vous effectuez des modifications (corrections de bugs ou fonctionnalités) via TDD, une fois terminé, il est probable que le test de fumée compagnon échoue. Vérifiez que les échecs sont ceux attendus en raison des modifications apportées et supprimez le test de fumée moins lisible, car votre test unitaire manuscrit a une couverture complète de ce composant amélioré. Assurez-vous que votre couverture de test ne diminue pas seulement rester le même ou augmenter.

  5. Lors de la correction de bugs, écrivez un test unitaire défaillant qui expose le bogue en premier.


Mettre à jour

6 ans après la réponse originale, j'ai une prise légèrement différente.

Je pense qu'il est logique d'ajouter des tests unitaires à tous les nouveaux codes que vous écrivez, puis de refactoriser les endroits où vous apportez des modifications pour les rendre testables.

Écrire des tests en une fois pour tout votre code actuel ne vous aidera pas - mais ne pas écrire des tests pour le nouveau code que vous écrivez (ou les zones que vous modifiez) n'a pas non plus de sens. Ajouter des tests en refactorisant / ajoutant des choses est probablement le meilleur moyen d'ajouter des tests et de rendre le code plus facile à maintenir dans un projet existant sans tests.

Réponse antérieure

Je vais lever quelques sourcils ici :)

Tout d'abord, quel est votre projet? Si c'est un compilateur, un langage ou un framework ou quoi que ce soit qui ne changera pas fonctionnellement pendant longtemps, je pense que c'est absolument fantastique d'ajouter des tests unitaires.

Cependant, si vous travaillez sur une application qui nécessitera probablement des changements de fonctionnalités (en raison de l'évolution des besoins), il est inutile de prendre cet effort supplémentaire.

Pourquoi?

  1. Les tests unitaires ne couvrent que les tests de code - que le code fasse ce pour quoi il est conçu - ne remplacent pas les tests manuels qui doivent toujours être effectués (pour identifier les bogues fonctionnels, les problèmes d'ergonomie et tous les autres problèmes)

  2. Les tests unitaires coûtent du temps! Maintenant, d'où je viens, c'est un produit précieux - et les entreprises choisissent généralement de meilleures fonctionnalités sur une suite de tests complète.

  3. Si votre application est même utile à distance aux utilisateurs, ils vont demander des modifications - vous aurez donc des versions qui amélioreront les choses, accéléreront et feront probablement de nouvelles choses - il y aura aussi beaucoup de refactorisation à mesure que votre code grandira. Maintenir une suite de tests unitaires dans un environnement dynamique est un casse-tête.

  4. Les tests unitaires ne vont pas affecter la qualité perçue de votre produit - la qualité que l'utilisateur voit. Bien sûr, vos méthodes peuvent fonctionner exactement comme elles l'ont fait le jour 1, l'interface entre la couche de présentation et la couche de gestion peut être vierge - mais devinez quoi? L'utilisateur s'en fiche! Obtenez de vrais testeurs pour tester votre application. Et le plus souvent, ces méthodes et interfaces doivent changer de toute façon, tôt ou tard.

Qu'est-ce qui sera le plus bénéfique? passer quelques semaines à ajouter des tests ou quelques semaines à ajouter des fonctionnalités? - Il y a beaucoup de choses que vous pouvez faire mieux que d'écrire des tests - Ecrire de nouvelles fonctionnalités, améliorer les performances, améliorer la convivialité, écrire de meilleurs manuels d'aide, résoudre les bogues en attente, etc etc

Maintenant, ne vous méprenez pas - Si vous êtes absolument certain que les choses ne vont pas changer pour les 100 prochaines années, allez-y, tuez-vous et écrivez ces tests. Les tests automatisés sont une excellente idée pour les API, où vous ne voulez absolument pas casser le code d'un tiers. Partout ailleurs, c'est juste quelque chose qui me fait expédier plus tard!


Cela vaut-il la peine d'investir dans une solution existante en production?
Oui. Mais vous n'avez pas besoin d'écrire tous les tests unitaires pour commencer. Ajoutez-les un par un.

Vaut-il mieux ignorer les tests pour ce projet et l'ajouter dans une future réécriture possible?
Non. La première fois que vous ajoutez du code qui brise la fonctionnalité, vous le regretterez.

Qu'est-ce qui sera le plus bénéfique? passer quelques semaines à ajouter des tests ou quelques semaines à ajouter des fonctionnalités?
Pour de nouvelles fonctionnalités (code) c'est simple. Vous écrivez d'abord le test unitaire puis la fonctionnalité. Pour l'ancien code, vous décidez en cours de route. Vous n'avez pas besoin d'avoir tous les tests unitaires en place ... Ajoutez ceux qui vous ont le plus blessés en n'ayant pas ... Le temps (et les erreurs) vous dira sur lequel vous devez vous concentrer;)


  • Oui, ça l'est. Lorsque vous commencez à ajouter de nouvelles fonctionnalités, cela peut entraîner une modification du code ancien et, comme résultat, une source de bogues potentiels.
  • (voir le premier) avant de commencer à ajouter de nouvelles fonctionnalités tout (ou presque) code (idéalement) devrait être couvert par des tests unitaires.
  • (voir le premier et le second) :). une nouvelle fonctionnalité grandiose peut "détruire" le vieux code travaillé.




tdd