BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Interviews Code Legacy et Stratégies de Test avec David Gageot

Code Legacy et Stratégies de Test avec David Gageot

Favoris
   

1. Bonjour David, merci d’accepter cette interview pour InfoQ dans le cadre du BreizhCamp. Pour ceux qui ne te connaissent pas, peux-tu te présenter en quelques mots ?

Je suis développeur freelance, et en ce moment j'aime bien dire que je suis test addict depuis 2001, c'est-à-dire que je ne pense que test, test, test ... et donc j'aime bien partager et discuter sur ce sujet avec d'autres personnes.

   

2. Tu es venu parler de “code legacy” aujourd’hui. Cette problématique est de plus en plus présente dans les conférences car finalement c’est un vrai challenge auquel nous sommes tous confrontés dans nos missions quotidiennes. Peux-tu nous présenter les enjeux de ce code pour les entreprises ?

Personnellement ou avec Jean-Laurent de Morlhon, nous avons fait plusieurs présentations sur le refactoring de code : ce qu'on appelle le code legacy, c'est du code déjà existant qui est plus ou moins joli, en général pas trop joli. On partait sur du code assez simple, et les gens nous disaient "mais ça ce n'est pas ce que j'ai dans la vraie vie, c'est sympa, c'est fun, mais cela ne correspond pas à ce que je rencontre. Dans la vraie vie, c'est encore pire". Nous avons donc décidé de travailler sur une présentation qui part du code d'une véritable application bancaire qui est assez atroce : des méthodes statiques, des trucs dans tous les sens… Cet exemple a beaucoup d'avantages, cela représente ce que les gens ont tous les jours au travail : remanier du code en prenant des risques à chaque fois. Des personnes viennent nous voir et nous demandent "Chez moi je n'arrive pas à faire ça, comment peux-tu m'aider ?". Et ça pour nous c'est important, et nous essayons avec nos présentations d'apporter des idées, des outils, des techniques, des stratégies pour travailler sur du code existant.

   

3. Peux-tu nous présenter les grandes lignes, les stratégies qu'il faut mettre en place ?

Ouh là ! Il faut venir à ma présentation… Les grandes stratégies, je l'ai déjà dit, je suis test-addict, donc ce qui est sûr c'est que l'on parle de tests. On a du code existant, comment on le teste, ou comment on améliore les tests, et comment faire cela vite. Comment au final faire un filet de sécurité pour être capable de remanier le code tout en ayant un sentiment de confiance assez important. Pour nous c'est la première chose la plus importante, ce premier axe, travailler sur comment tester du code existant, qui n'a pas été pensé pour être testé. Ensuite, ce que l'on aime partager, ce sont des techniques qui vont permettre au développeur de se focaliser sur leurs tâches. Ça c'est valable pour du code legacy mais aussi pour tout. Les gens devraient beaucoup plus se timeboxer, ils devraient beaucoup plus adresser un seul problème à la fois. Les développeurs souvent font trois choses à la fois, c'est le "oui mais", si je fais ça, alors je ne fais pas ça, or je veux tout faire à la fois, et au final on ne fait rien. Donc on met des petites stratégies, techniques pour se focaliser, découper le problème, avancer avec une boucle de feedback très courte, pour avancer, avancer, avancer. Voilà les axes sur lesquels on essaie de travailler.

   

4. Le code legacy d’une application représente souvent un énorme morceau de volume de code. Si je dois mettre en place ces tests dans ma mission, par quel bout dois-je commencer ?

C'est super dur de répondre. Tu as plusieurs façons de faire et ce n'est jamais facile de trancher. Parfois tu vas vouloir juste rajouter une fonctionnalité, et pour cela tu vas devoir toucher à du code existant, donc peut-être que la bonne stratégie c'est de faire une suite de non régression sur le code que tu vas toucher. Tu ne vas pas faire des tests fonctionnels, tu vas vraiment faire une suite de non régression pour figer le comportement. Ensuite tu vas pouvoir re-travailler le code sans prendre trop de risques. Si par contre, tu veux documenter plus le code, donc rajouter plus de tests métiers, qui n'ont pas pour objectif de donner un filet de sécurité mais qui permettent d'expliquer un peu ce que fait le code, ça peut aussi être une stratégie. Mais bon, ce qui est sûr, c'est que nous ce que l'on adresse le plus c'est comment construire un filet de sécurité autour de code existant, et comment faire cela vite, en allant au plus efficace.

   

5. En ce qui concerne les technologies, elles sont souvent hétéroclites souvent à cause ou grâce au nombre de personnes qui sont passées sur le projet. Quels sont les outils qui vont m’aider à tester correctement mon application ?

C'est compliqué de répondre à ça. Je vais peut-être répondre à côté de la plaque, mais il y a des outils qui marchent quelle que soit la technologie. Par exemple, dans notre atelier, nous expliquons comment l'analyse de couverture de code peut aider les gens à prendre des décisions. Ils voient que ce code-là est couvert ou non par des tests, ça c'est intéressant. C'est un outil qui existe dans à peu près toutes les technos, et qui permet aux développeurs de les aider à faire des choix. Après, même si tu as des stacks technologiques super compliquées, tu peux quand même prendre ton système comme un tout, comme une grosse boîte noire, et faire des tests par l'IHM, ou par le batch, et tu t'en fiches un petit peu de ce qu'il y a en-dessous. Du coup tu vas avoir des tests qui sont un peu longs, un peu fastidieux, qui vont traverser plein de couches, mais ça se fait. Donc là, tu t'abstraies un peu de tout ce qui est traversé. Mais il n'y a pas de solution miracle. C'est au cas par cas, et c'est pour cela que l'on insiste beaucoup, pas tant sur les outils, que sur les bons réflexes. Quoi qu'il arrive, les réflexes, c'est découper le problème, avancer avec du feedback, si un test est trop long, c'est un problème car le feedback est trop long. De la même façon, les gens travaillent souvent sur plusieurs choses à la fois, ils ont du mal à faire des "baby steps" comme on dit. Ça c'est plus important que tous les outils.

   

6. Il existe différents types de tests réalisés par le développeur : tests unitaires, tests d’intégration, tests d’IHM, … Faut-il privilégier par exemple les tests unitaires lorsque je teste du code legacy ?

Je dirais que cela dépend, mais en général c'est dur de faire des tests unitaires sur du code legacy. On a plutôt tendance à traverser plein de couches et donc de faire des tests bout en bout. Parce qu'au début c'est ce qui est plus facile. Il y a plein de technos au milieu, rien n'est fait pour mettre des mock ou se brancher à des couches intermédiaires, alors on teste de bout en bout. Alors c'est long, les tests sont longs, mais c'est facile à écrire. Ce n'est pas une fin en soi, mais c'est un bon début. Quitte à taper de tout en haut, et débrayer au niveau de la base de données, en la mockant. Parfois un test bout en bout, ça ne teste pas dix couches mais deux. Ce n'est pas un test unitaire mais ça peut être rapide aussi.

   

7. Quels objectifs peut-on se fixer lorsque l’on souhaite tester le code-legacy d’une application. Par exemple, quel taux de couverture de code par les tests peut-on raisonnablement se fixer ?

Déjà, on teste rarement pour tester. En général, on a un objectif derrière. Par exemple, rajouter une fonctionnalité, ou alors il y a un bout de code qui est devenu vraiment impossible à maintenir, et on sait qu'un jour on va vouloir mettre des nouvelles fonctionnalités et on n'en peut plus de travailler sur un tel code spaghetti. Donc généralement l'objectif existe à côté. Maintenant comment on peut juger pour savoir si on teste suffisamment le code, oui la couverture du code par les tests est une métrique intéressante. Dans la présentation de ce matin, on montrait comment couvrir 100% du code, et on me disait, oui mais 100% du code ça ne veut rien dire. Oui mais, oui mais, beaucoup de oui mais. Retenons le positif : avant on avait zéro, maintenant on a cent. C'est forcément un peu mieux quand même. Ce n'est pas parfait, c'est un peu mieux et après on peut essayer de faire que ces 100% soient des vrais 100%. On rajoute des assertions, des cas aux limites. C'est une bonne première étape. Se dire, 100% ça veut rien dire alors je ne le fais pas, c'est une mauvaise décision en fait. Donc la couverture est un bon indicateur, il n'est pas suffisant mais il nous aide.

   

8. D’un point de vue économique, tester du legacy-code ce n’est pas neutre : on revient sur des choses qui ont déjà été réalisées. Peux-tu nous donner un ordre de grandeur du temps supplémentaire passé pour tester du legacy-code ?

Aucune idée. Ce qui est sûr c'est qu'en général, ceux qui en arrivent à ça, sont dans une situation de cul-de-sac : je veux rajouter des fonctionnalités et je n'y arrive plus. Parce que finalement, il n'y a que ça qui peut les amener à tester du code legacy. Jusque-là le code a été construit sans tests, c'est que les gens arrivaient bien à vivre sans. Et le jour où on arrive plus à vivre sans, là on a un impératif et on commence à en écrire. Donc les tests ne viennent pas juste parce que l'on a envie de tester le code. Ils viennent parce que l'on a un autre impératif qui est, ça ne marche plus, on ne sait plus quoi faire, on ne sait pas rajouter une nouvelle fonctionnalité. Souvent c'est le rajout de nouvelles fonctionnalités, qui dit rajout de code dans de l'existant, dit faudrait peut-être le couvrir avant par des tests, le simplifier avant. Donc je ne sais plus si c'était la question mais c'était ma réponse

   

9. Et, par comparaison, avec une application qui a été continûment testée lors de son développement ?

Forcément si on teste en continu une application, on a gagné des choses, ce sera plus facile de la faire évoluer, à condition tout de même que lorsque l'on rajoute du code et des tests, on en profite pour refactorer et simplifier à chaque étape. Car si l'on ne fait que des tests, du code, des tests, du code, on va quand même faire un bousin à la fin, du Test-Driven Bousin, c'est sympa mais ce n'est pas le but. Mais globalement quand même si on fait des tests régulièrement avant d'écrire des fonctionnalités ou juste après, ça va être beaucoup plus facile de travailler. Et ça nous évite à un moment de nous taper la tête contre le mur avec du code legacy, et se dire, faut que je passe deux jours à tester cette classe-là, je ne sais plus par quel bout prendre le truc. C'est de la frustration. Donc on peut éviter la frustration en testant tôt.

13 déc. 2013

BT