Tests unitaires anciens / hérités cassés


13

Je travaille pour une grande entreprise et je suis responsable d'une grande application java avec des milliers de tests junit. Depuis que je suis passé à ce poste, 200 à 300 tests ont été brisés (probablement cassés pendant des années). Les tests sont anciens et fragiles et ils sont un gâchis de dépendances spaghetti qui se terminent généralement par des données de bac à sable en direct.

Mon objectif est de réussir à 100% les tests afin que nous puissions briser les échecs des tests unitaires, mais je ne peux pas le faire avant d'avoir résolu les tests brisés. J'ai très peu de budget parce que le budget de maintenance est principalement pour le support, mais mon équipe a identifié et corrigé les tests de fruits bas (principalement des problèmes de configuration / ressources locales) et nous en sommes à 30-40 tests vraiment laids.

Quelles sont les opinions sur les meilleures pratiques? Je ne pense pas que les tests soient utiles, mais je ne sais pas non plus ce qu'ils testent ou pourquoi ils ne fonctionnent pas sans creuser, ce qui prend du temps et de l'argent que nous n'avons probablement pas.

Je pense que nous devrions documenter les statuts des tests cassés avec tout ce que nous savons, puis supprimer ou ignorer complètement les tests cassés et entrer un bug / élément de travail de priorité inférieure pour enquêter et les corriger. Nous serons alors à 100% et commencerons à obtenir une réelle valeur ajoutée des autres tests et si nous avons une manne de maintenance / refactoring, nous pourrons les reprendre.

Quelle serait la meilleure approche?

Edit: Je pense que c'est une question différente de cette question parce que j'ai une direction claire pour les tests que nous devrions écrire à l'avenir, mais j'ai hérité des tests défaillants hérités à adresser avant que le grand ensemble actuel de tests ne devienne significatif.


1
Je suis tout à fait d'accord pour dire que vous devez vous débarrasser de 30 à 40 tests laids. Cependant, "si nous avons une manne de maintenance / refactoring, nous serons en mesure de les reprendre" sonne comme un vœu pieux. Je ne suis pas sûr qu'il y ait un réel avantage à les documenter comme un élément de faible priorité car ces éléments ont l'habitude de ne jamais être traités.
David Arno

1
Je recommande de consulter ce livre: Travailler efficacement avec Legacy Code . Une recommandation de livre n'est pas une réponse à votre question, mais vous y trouverez beaucoup de bons conseils concernant les tests unitaires.

4
Cela peut être un doublon de quelque chose, mais ce n'est pas cette question. Il ne s'agit pas de savoir comment éviter d'écrire des tests unitaires fragiles, mais comment gérer une base de code héritée avec des tests unitaires déjà écrits qui échouent.

1
Il semble que vous ayez déjà trouvé votre solution.
Doc Brown

2
@gnat je ne suis pas d'accord. D'après mon expérience personnelle, il y a une grande différence entre "quelque chose a cassé beaucoup de mes tests unitaires hier soir" et "J'ai hérité de beaucoup de vieux code avec des tests unitaires échouant assez longtemps, personne ne sait pourquoi." L'un est un problème avec le développement actuel, l'autre est un problème avec les logiciels hérités. Deux approches différentes sont nécessaires ici. La première réponse à la question liée ne traite pas des aspects hérités.

Réponses:


17

Ce que je ferais, c'est d'abord désactiver les tests qui échouent et ont toujours échoué.

Faites en sorte qu'un test échoue soit important.

Au fur et à mesure que vous enquêterez, vous pourrez peut-être demander aux personnes qui sont avec votre entreprise depuis plus longtemps à leur sujet, il peut y avoir beaucoup de connaissances tribales à leur sujet que vous pouvez documenter / capturer. Peut-être à partir de vos journaux VCS. "Oh, ce test a toujours échoué depuis que nous sommes passés à X" ou d'autres informations peuvent être utiles.

Une fois que vous connaissez la fonctionnalité testée, vous pouvez déterminer:

  • Nous soucions-nous de ce test
  • Quelle est l'importance de ce test

Et puis faites une liste de priorités.

Il est probable que rien sur cette liste n'est suffisamment important pour obtenir plus de temps plus tard, car il est ignoré depuis des années déjà. Je ne passerais donc pas trop de temps / ressources à documenter et analyser tous ces tests cassés.


1
J'aime l'idée de désactiver les tests à l'avance, mais un environnement conservateur pourrait préférer des mouvements incrémentiels plus petits. Je suppose que cela dépend de votre entreprise?
Aaron Hall

1
@AaronHall - Je pense que si vous examinez vos besoins immédiats de changement de code (correctifs et améliorations) et identifiez les tests défectueux qui leur sont associés, vous pouvez activer tous ces éléments, évaluer et corriger les tests, apporter vos modifications de codage avec la compréhension les tests réussissent, sont corrigés ou sont supprimés.
JeffO

6

Je ferais ce qui suit:

  1. Essayez de déterminer exactement ce que les tests en échec tentent de valider.

  2. Triage - si certains tests tentent de tester des choses sans importance comme (un ancien) état du monde, supprimez-les. Si vous réalisez que certains d'entre eux essaient de valider quelque chose d'important, essayez de déterminer si ces tests le font correctement. S'ils testent incorrectement, faites-les tester correctement.

  3. Corrigez tout ce qui ne va pas avec votre code de production maintenant que vous avez de bons tests.

N'oubliez pas la comptabilité, chaque ligne de code est un passif, mais peut être incorrectement évaluée comme un actif. La deleteclé peut créer beaucoup de valeur pour votre entreprise.


Une idée de triage en équipe est très agréable!

De bonnes idées, mais OP a déjà dit qu'il n'avait pas de ressources pour effectuer une analyse approfondie, donc malheureusement il ne pourra pas les utiliser.
TMN

Le triage consiste à rationner des ressources limitées là où elles créeront le plus de valeur. Voici un article de blog pertinent sur le thème du triage et des logiciels: softwaretestingclub.com/profiles/blogs/…
Aaron Hall

5

200-300 tests cassés (probablement cassés pendant des années).

Aie! J'ai fait face à une situation similaire une fois, mais avec 7 tests échouant, où l'équipe a commencé à ignorer le fait qu'ils avaient échoué pendant des mois en raison d'une mentalité "toujours croquante".

Mon objectif est de réussir à 100% les tests afin que nous puissions briser les échecs des tests unitaires, mais je ne peux pas le faire avant d'avoir résolu les tests brisés.

J'étais obsédé par un objectif similaire même si je n'étais qu'un développeur junior dans l'équipe parce que je remarquais une accumulation où d'autres tests échouaient au fil des mois. Je voulais que nous transformions ceux des "avertissements" en erreurs de construction (peut-être un peu désagréablement pour le reste de l'équipe).

Je pense que nous devrions documenter les statuts des tests cassés avec tout ce que nous savons, puis supprimer ou ignorer complètement les tests cassés et entrer un bug / élément de travail de priorité inférieure pour enquêter et les corriger. Nous serons alors à 100% et commencerons à obtenir une réelle valeur ajoutée des autres tests et si nous avons une manne de maintenance / refactoring, nous pourrons les reprendre.

Ce sont mes pensées aussi. Vous pouvez désactiver temporairement tous ces tests défectueux et les visiter lentement et les corriger au fil du temps. Il est important de planifier ces correctifs si vous les considérez vraiment importants, même s'ils sont de faible priorité, car il est facile pour ces éléments de ne pas être résolus. La priorité pour moi est de veiller à ce qu'aucun nouveau test n'échoue.

Comme tout type d'avertissement, s'ils ne cassent pas la construction, ils ont tendance à s'accumuler rapidement. Cela suppose que ce type de dynamique d'équipe où l'habitude d'ignorer les avertissements (tests échoués dans ce cas) peut rapidement entraîner l'introduction de plus d'avertissements et réduire la tentation de garder ces avertissements à zéro.

Une équipe très consciencieuse pourrait ne pas souffrir de ces problèmes et éviter d'introduire de nouveaux avertissements (nouveaux échecs dans les tests), mais il est certainement plus sûr d'aller un peu plus fort et d'exercer une stratégie de prévention en les transformant en erreurs qui doivent être corrigées avant une processus de fusion.

Donc, ma suggestion est la même que la vôtre (bien que ce ne soit qu'une opinion forte - peut-être peut-être un peu étayer cela avec des mesures et une réponse plus scientifique). Désactivez ces anciens tests et placez-les dans le calendrier pour éventuellement les corriger. La première priorité est de s'assurer que ce problème ne s'accumule pas et ne s'aggrave pas en s'assurant que les tests qui réussissent actuellement ne finiront pas par être ignorés s'ils commencent à échouer.


4

D'une certaine manière, vous avez de la chance. Il vaut mieux avoir des tests qui échouent et ne devraient pas (ils vous donnent au moins un avertissement que quelque chose ne va pas) que d'avoir des tests qui réussissent et ne devraient pas (ce qui vous donne un faux sentiment de sécurité).
Bien sûr, si vous avez le premier, il est fort probable que vous ayez également le second (donc les tests réussissent mais devraient échouer).

Comme indiqué précédemment, désactivez pour l'instant ces tests qui échouent, mais demandez-leur d'imprimer un message dans votre journal de test pour les rappeler constamment.
Mais vous devez certainement trouver les ressources pour parcourir toute votre suite de tests afin de trouver et d'éliminer les tests qui réussissent et ne devraient pas, car chacun d'eux signifie qu'il y a un bogue dans votre code que vous ne détectez pas actuellement dans votre cycles d'essai.

En utilisant ce nuage sombre qui pèse sur la base de code, vous pourriez bien obtenir un budget pour un examen complet de vos tests, si vous le jouez correctement et ne leur dites pas simplement que vous pensez que certains tests devraient être examinés parce qu'ils semblent échouent alors qu'ils ne devraient pas, mais que vous ne croyez pas que vos tests détectent correctement les erreurs dans votre code, que l'ensemble de tests ne peut pas être fiable pour faire son travail.
Quand je l'ai fait dans une entreprise précédente, je travaillais pour un tel examen a révélé que des centaines de tests ont été écrits avec des hypothèses incorrectes sur ce que le code DEVRAIT faire, conduisant au code (qui a été écrit en utilisant les mêmes hypothèses incorrectes) a réussi les tests lorsque vraiment ça n'aurait pas dû. La résolution de ce problème a résolu de nombreux bugs de cas d'angle qui (bien que la plupart n'étaient pas critiques) auraient pu faire tomber certains systèmes importants.


3

Tout test unitaire qui échoue devrait entraîner la rupture de la version. Je vous remercie de l'avoir réalisé et d'avoir fixé cet objectif. L'esprit humain ne peut guère ignorer quoi que ce soit de plus complet que la source d'une fausse alarme persistante .

Jetez ces tests et ne regardez pas en arrière. S'ils échouent depuis des années et n'ont pas été résolus à ce jour, ils ne sont pas une priorité.

En ce qui concerne les connaissances tribales, si les personnes possédant les connaissances tribales sont toujours là, elles auraient dû corriger les tests défaillants. Sinon, là encore, ce ne sont pas une priorité.

S'il n'y a pas de connaissances tribales, vous et votre équipe devez vous approprier la logique. Les tests échoués peuvent être plus trompeurs qu'utiles - le monde peut avoir évolué.

Créez de nouveaux tests pertinents et continuez à écrire du bon code.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.