SlideShare une entreprise Scribd logo
Tester du Legacy Code,
mission impossible ?
Bon après-midi, Ethan.
• Votre mission, si vous l’acceptez, consiste à vous
occuper d’un système informatique qui n’est pas
nouveau ni trop vieux, mais qui n’a aucun tests
automatisé.
• Par contre, il est au cœur de plusieurs traitements
d’affaires critiques. Vous allez avoir à ajouter de
nouvelles fonctionnalités et a en faire l’entretien.
• Nous avons observés les choses suivantes:
– Classes de la logique d’affaire qui fait 32 000 lignes.
– Une interface de 2000 lignes (incluant une ligne de
commentaire par méthode) été créé récemment pour vous
permettre d’introduire des tests.
• Ce message s’auto-détruira dans 5 secondes …..
Bon après-midi, Ethan.
• Votre mission, si vous l’acceptez, consiste à vous
occuper d’un système informatique qui n’est pas
nouveau ni trop vieux, mais qui n’a aucun tests
automatisé.
• Par contre, il est au cœur de plusieurs traitements
d’affaires critiques. Vous allez avoir à ajouter de
nouvelles fonctionnalités et a en faire l’entretien.
• Nous avons observés les choses suivantes:
– Classes de la logique d’affaire qui fait 32 000 lignes.
– Une interface de 2000 lignes (incluant une ligne de
commentaire par méthode) été créé récemment pour vous
permettre d’introduire des tests.
• Ce message s’auto-détruira dans 5 secondes …..
MISSION
Qui sommes-nous ?
• Karl Métivier
– Architecte Logiciel
– Développeur
– Coach Agile
– Formateur
• Yves St-Hilaire
– Soutien au développement
– Accompagnement, mentorat
– Développement BI
Histoire d’un système
• On change notre processus, on passe
à Scrum.
• On nous demande d’ajouter des tests
unitaires automatisés au code
existant.
– Oups, le système n’a pas été prévu
pour cela…
• Comment avoir le temps pour cela ?
– Réunion pour discuter des bogues
courants.
– Documentation à mettre à jour.
• Au final, problème de dette
technique.
Code Legacy
C’est quoi pour vous ?
Définitions pour le Legacy Code
• Du code Legacy, c’est du code:
– sans tests unitaires - Michael Feathers
– plus vieux que ceux qui y travaillent
– modifications en mode « patchage »
– nécessitant un guide du marais pour
s’y retrouver!
• Enfreint constamment les principes
SOLID
• On n’ose pas y toucher.
• Et les Legacy Systems ?
Code « Legacy »
Quand vous avez à
travailler avec ça, c’est
quoi votre feeling ?
Pourquoi est-on pognés avec ça ?
• Délais courts de développement
• Plusieurs personnes y sont passées
• Conception Legacy?
–Architecture identique au dossier fonctionnel
• Peu d’efforts alloués pour l’amélioration
–Le système fonctionne, on n’y investit rien
Quel est le problème au juste ?
Architecture incohérente
La conception n’est pas conçue pour les tests
Dépendances cachées
Code «pas propre» et bien d’autres
Le dilemme du refactoring
• Pour faire du
refactoring, on doit
avoir des tests
• Pour mettre en place
des tests, on doit
refactoriser.
Tester le Legacy Code:
1 - Comment le faire ?
Cas 1 – Classe sans injection de dépendances
• Pas de possibilité d’injecter un mock
• Plusieurs appelants l’utilisent, souvent on ne
peut les modifier
Cas 1 – Classe sans injection de dépendances
Comment ?
• Pour la classe qu’on veut mocker :
– Ajout d’une interface
• À la classe à tester :
– Ajout d’un constructeur permettant l’injection
– On lui injectera l’instance à utiliser, ou une Factory
• Les appelants ne sont pas impactés
• On permet l’injection, mais les appelants existants
ne l’utilisent pas
Cas 1 – Ajout d’injection – Comment
public class MyClass {
private IFileReader reader;
public MyClass(string fileName) {
// original code
// ...
reader = new MyFileReader(fileName);
}
public MyClass(IFileReader injectedReader) {
// original code
// ...
reader = injectedReader;
}
}
Cas 1b – Classe sans injection de dépendances
Comment ?
• Autre technique : Patron « Test Specific Subclass »
• Classe à mocker : ajout d’une interface à la classe
• Classe à tester :
– Ajout d’une méthode virtuelle
« ObtenirInstanceClasseAppelee »
• Dans le projet de test :
– Hériter de la classe à tester
– Implémenter notre propre
« ObtenirInstanceClasseAppelee »
Cas 1b – Test specific subclass – Comment?
public class MyClass {
protected int someProtectedInfo = 42;
private IFileReader reader;
public MyClass(string fileName) {
reader = GetReader(fileName);
}
protected virtual IFileReader GetReader(string fileName) {
return new MyFileReader(fileName);
}}
public class MyClassSpecificSubclass : MyClass {
public IFileReader InsertMockHere;
public MyClassSpecificSubclass(IFileReader aReader) {
InsertMockHere = aReader;
}
protected override IFileReader GetReader(string fileName) {
return InsertMockHere;
}
public int GetInternalInfo() {
return someProtectedInfo;
}}
Cas 2 – La classe iceberg
• Reconnaissable facilement
– Grosse
• Milliers, dizaines de milliers de lignes
– Peu de méthodes publiques
• Comptées sur une seule main
• C’est quoi le problème?
– Grande complexité cyclomatique
– Interdépendances entre les méthodes
– Donc difficile à tester
Cas 2– La classe iceberg – Comment?
• Identifier les différentes responsabilités
– Noms de méthodes
– #Region ou zones de commentaires
• Refactoriser en plusieurs classes
• Si impossible :
– Identifiez les méthodes qui seraient publiques avec un
refactoring
– Changer la visibilité et testez ces méthodes
Cas 2– La classe iceberg – Exemple (classe
simplifiée!)
Cas 3 – Méthode statique
• Une méthode statique, l’équivalent d’un
singleton
• Une seule version possible pour tout le système
– Donc pas mockable
• Pas un problème pour la tester
• Mais un véritable problème pour tester les
méthodes qui l’appellent
Cas 3 – Méthode statique – Comment?
• Ajout d’une interface à la classe
• Ajout de méthodes d’instance
correspondant aux méthodes statiques
– DRY : la méthode d’instance peut
appeler la méthode statique!
– Les appelants ne sont pas affectés
• Éventuellement on pourra enlever
complètement les méthodes statiques
Cas 3 – Méthode statique – Code
public class ClassUnderTest
{
public void MethodUnderTest()
{
// ...
var number = AnotherClass.GetNumber();
if (number > 0)
{ }
else
{ }
// ...
}
}
public class AnotherClass
{
public static int GetNumber()
{
return 4;
}
}
Cas 3 – Méthode statique – Code
public class ClassUnderTest {
private IAnotherClass _anotherClass;
public ClassUnderTest() { _anotherClass = new AnotherClass(); }
public ClassUnderTest(IAnotherClass anotherClass) { _anotherClass = anotherClass; }
public void MethodUnderTest() {
// ...
var number = _anotherClass.GetNumber();
if (number > 0)
{ }
else
{ }
// ...
}
}
public class AnotherClass: IAnotherClass {
public static int GetNumber() { return 4; }
int IAnotherClass.GetNumber() {
return AnotherClass.GetNumber();
}
}
Mais en avez-vous vraiment besoin ?
• Parfois, l’ajout de tests unitaires
demande beaucoup d’efforts
pour peu de gains
• Évaluer d’autres opportunités
– CodedUI / Selenium
– Tests intégrés, mocker
uniquement les données
– Tests comparatifs
• Pas toujours les meilleures
pratiques, mais faut s’adapter au
contexte!
Comment le BDD m'a aidé dans mon débogage
• Partir d’un cas d’utilisation (déjà
implémenté) et le descendre en étape BDD
du début (contrôleur UI), passer par le
service et aboutir dans une BD en mémoire
• C’est long
• On vérifie toutes les dépendances et on
traverse toutes les couches
• C’est long, mais après coup notre
compréhension du code s’est vraiment
améliorée
• En plus, le test BDD reste et peut être
rejoué !
État d’esprit pour déboguer de Legacy Code
• Voir le code comme une scène de
crime
• Faire un profil de l’agresseur (ou de
ce qui cause le problème)
• Analyser les hot-spots
• Calculer la complexité
• Faire la dissection de l’architecture
• Cartographier une carte de
connaissances de votre système
• Impact sur l’existant
Tester le Legacy Code:
2 - Comment avoir le droit ?
Versus la résistance
C’est impossible d’en faire chez nous car…
• Nous autres, c'est différent
• On a un système de mission
critique à l'entreprise
• Nos utilisateurs ont le contrôle et
le budget
• Notre système est très complexe
• On a des données nominatives
• …
C’est notre devoir d’être professionnel
Du code propre n’apparaît
pas de lui-même:
• Vous avez à le produire
• Vous avez à le maintenir
• Vous en faites un
engagement professionnel
Combattre le résistance en discutant
• La plupart des gestionnaires
défendent leurs échéanciers et les
requis avec passion.
– Cela fait partie de leurs responsabilités.
• Votre responsabilité :
– Défendre également le code avec
passion.
• Ayez le courage de dire la vérité et
de travailler pour arriver à un terrain
d’entente.
• Discuter avec votre PO ou votre chef
d’équipe. Il devrait être sensible à la
qualité produite. Donc de supporter
l’équipe quand il sent qu’un
refactoring est nécessaire.
Il faut alors être stratégique
• Cela ne donne pas grand chose de
travailler sur du code qui va bien et qui
n’a pas de problème régulièrement.
Don’t fix it, if it’s not broken.
• Trouver les points chauds de votre
système:
– Bogues réguliers
– Difficiles à travailler
– Modification à faire prochainement
– Logique d’affaires importante
• Progresser par la technique des
petits pas.
Bien évaluer
Valeur de cet investissement :
• Potentiel
• Bloquant actuel
• Criticité du système
• Nombre de personnes impactées
• Durée de vie du système
• Refonte prévue?
La résistance peut donc être combattue
• C’est souvent le premier pas le
plus difficile.
• Ne pas oublier :
– Être stratégique
– Évaluer le tout
• Y aller un test à la fois:
– Et son Refactoring de code
qui le suit.
En fait, on en revient à la transparence
Le premier pilier de l’agilité!
3. Comment tester du
Legacy Code au jour le jour
et s’en prémunir?
Comprendre le code
• Les tests nous apportent une façon de
comprendre le code.
• D’une certaine manière, les tests nous
font travailler dur pour arriver à cette
compréhension.
• Il est facile de faire des tests en
présence d’une bonne conception.
Ne pas hésiter à utiliser des outils modernes
• Legacy != outils désuets
• Exemples :
– Intégration continue
– Dernière version de l’IDE
– Dernières versions des
librairies et frameworks
– Système Legacy dans Docker
Ne pas oublier les bases
• OOP
• Clean Code
• Maîtrisez et appliquez les
principes SOLID
• Boy Scout Rule
• Agile Modeling (Scott Ambler)
Se prémunir contre le Legacy Code à la base
• Les développeurs doivent
demander Quoi, Pourquoi et
pour Qui avant de trouver le
Comment.
• Ce n’est pas aux analystes et
utilisateurs de leur dire le
Comment.
• On veut savoir du client/PO
qu’est-ce qu’ils veulent,
pourquoi ils le veulent et pour
qui cela va être utile.
Faire la conception en équipe
• Les meilleures conceptions sont
effectuées en équipe, et non par
une seule personne.
• La compréhension de
l’architecture ainsi que son
adoption est répandue dans toute
l’équipe.
• Pourquoi s’en passer ?
Ou du Mob Programming !
• Approche où l’équipe
complète (client, analyste
et PO aussi) travaille sur la
même chose :
– Au même endroit
– En même temps
– Sur le même ordinateur
• Un peu similaire au pair
programming
En résumé, nous avons vu…
• C’est quoi du Legacy Code
• Comment faire pour le tester
• Comment affronter la résistance
• Comment s’en prémunir au jour le jour
Alors, tester du du Legacy Code,
• Met à l’épreuve et renforce nos
habilités en:
– Programmation Orientée-Objet
– Conception & Architecture
• Offre un challenge qui peut donc
être instructif et amusant !
• Nous rend plus professionnel en bout
de ligne.
Comment vous en sortez-vous avec le Legacy Code ?
Références 1/2
• Podcast Hanselminutes 2016-08-05 « Learning to love Legacy Code
with Andrea Goulet from CorgiByte »
– http://hanselminutes.com/539/learning-to-love-legacy-code-
with-andrea-goulet-from-corgibytes
• Patron « Test Specific Subclass »
– http://xunitpatterns.com/Test-Specific%20Subclass.html
• XKCD Goto
– https://xkcd.com/292/
Autres références
• Lectures suggérées
• Beaucoup de
connaissances et
d’information sur le
‘net
Pour nous rejoindre
• Karl Métivier
– Courriel: kmetivier@facilite.com
– LinkedIn: https://www.linkedin.com/in/karlmetivier/fr
– Twitter: @karlmet
– Blogue: https://excellenceagile.com/
• Yves St-Hilaire
– Courriel: yves.sthilaire@gmail.com
– LinkedIn: www.linkedin.com/in/yves-st-hilaire
– Twitter: @sthiy

Contenu connexe

PPTX
Architecture express pour petits projets
PPTX
Mon Agilité est plus grosse que la tienne!
PPTX
Nos leçons apprises avec la méthode kanban
PPTX
Architecture express pour petits projets
PPTX
En route vers l'optimisation - Agile tour Sherbrooke 2017
PPTX
Les Bases des Méthodes Lean/Agile
PDF
Initiation Scrum
PDF
Kanban, un outil simple de gestion de la production.
Architecture express pour petits projets
Mon Agilité est plus grosse que la tienne!
Nos leçons apprises avec la méthode kanban
Architecture express pour petits projets
En route vers l'optimisation - Agile tour Sherbrooke 2017
Les Bases des Méthodes Lean/Agile
Initiation Scrum
Kanban, un outil simple de gestion de la production.

Tendances (20)

PDF
Large Scale Scrum
ODP
Les méthodes Agiles - Introduction
PDF
Introduction à l'agilité ensmse
PDF
How to fail at benchmarking?
PPTX
Contractualisation agile : Saison 2 (atm)
PPTX
Gestion de projets agiles avec scrum actiskills
PDF
Lunch learn 5 sep2013
PPT
Agile presentation
PDF
Présentation de l’agilité
ODP
Agile Tour 2010 - Mise en place d'un projet agile
PPTX
Introduction à l'Agilité - Cours complet 1 jour
PPTX
Méthodes agiles vs méthodes classiques
PPT
Développement en méthode agile
PDF
L'agilité en quelques slides
PDF
Scrum Day 2014 - Êtes-vous prêts pour le modèle Spotify ?
PDF
REX Kanban dans plusieurs contextes, par Couthaïer Farfra (Agile4Me)
PDF
Agile - DevOps : la boite à outils
PPTX
Lean Kanban Une Inversion de Controle
PPTX
Agilité à budget fixe en phase d'avant-vente. Que proposer ?
PDF
Modèle de maturité CMMi-DEV
Large Scale Scrum
Les méthodes Agiles - Introduction
Introduction à l'agilité ensmse
How to fail at benchmarking?
Contractualisation agile : Saison 2 (atm)
Gestion de projets agiles avec scrum actiskills
Lunch learn 5 sep2013
Agile presentation
Présentation de l’agilité
Agile Tour 2010 - Mise en place d'un projet agile
Introduction à l'Agilité - Cours complet 1 jour
Méthodes agiles vs méthodes classiques
Développement en méthode agile
L'agilité en quelques slides
Scrum Day 2014 - Êtes-vous prêts pour le modèle Spotify ?
REX Kanban dans plusieurs contextes, par Couthaïer Farfra (Agile4Me)
Agile - DevOps : la boite à outils
Lean Kanban Une Inversion de Controle
Agilité à budget fixe en phase d'avant-vente. Que proposer ?
Modèle de maturité CMMi-DEV
Publicité

En vedette (13)

PPTX
Passez un test de la vue - Outils visuels pour y voir clair!
PPTX
Catalyser votre transition agile avec le codéveloppement
PPTX
Rétrospectives en 4 actes
PPTX
Why certain code is hard to test?
PPTX
Java annotation
PPTX
Martin folwer
PPT
Software Design Patterns
PPTX
Estimation initiale dun projet agile de Mathieu Boisvert
PDF
La co-création, ou comment innover avec le client?
ODP
Symfony Best Practices
PDF
Ctifl Reperes Semo Cocreation Fruit Et LéGumes Def
PDF
Du JavaScript propre ? Challenge accepted ! @Devoxx France 2013
PDF
4D Summit2013 refactoring
Passez un test de la vue - Outils visuels pour y voir clair!
Catalyser votre transition agile avec le codéveloppement
Rétrospectives en 4 actes
Why certain code is hard to test?
Java annotation
Martin folwer
Software Design Patterns
Estimation initiale dun projet agile de Mathieu Boisvert
La co-création, ou comment innover avec le client?
Symfony Best Practices
Ctifl Reperes Semo Cocreation Fruit Et LéGumes Def
Du JavaScript propre ? Challenge accepted ! @Devoxx France 2013
4D Summit2013 refactoring
Publicité

Similaire à Tester du legacy code, mission impossible ? (20)

PDF
TDD/BDD: ou comment j’ai appris à ne plus m’en faire avec les tests (et la doc)
PPTX
Le pilotage par les tests
PDF
TDD (Test Driven Developement) et refactoring
PPTX
C'est quoi, du bon code ?
PPTX
[Agile Tour Paris 2014] Comment rendre testable du code qui ne l'est pas ?
PPT
Tests Logiciel
PPS
Formation tests decembre2010
PPT
Industrialisation Du Logiciel - Introduction Et Bonnes Pratiques
PPT
Industrialisation Du Logiciel Introduction Et Bonnes Pratiques V1.4
PDF
Tour d'horizon des tests
PPTX
Présentation des test driven development aka tdd
PPT
Bbd dans le flow nov.2012
PDF
Mockito - Design + tests par Brice Duteil
PPTX
PHPTour Lyon 2014 - Conférence - Tests unitaires Je veux mes 80% de couvertur...
PPTX
Présentation Alt.net - Tests unitaires automatisés
PPTX
Keynote agile grenoble 2013
PPTX
Pourquoi vous ne pouvez pas tester votre code
PDF
Tests de caractérisation : à l’assaut de votre code "Legacy" patrimonial [FR]
PDF
Pratiques de développement pour équipes Agile
PDF
Test driven development v0.2 20121221
TDD/BDD: ou comment j’ai appris à ne plus m’en faire avec les tests (et la doc)
Le pilotage par les tests
TDD (Test Driven Developement) et refactoring
C'est quoi, du bon code ?
[Agile Tour Paris 2014] Comment rendre testable du code qui ne l'est pas ?
Tests Logiciel
Formation tests decembre2010
Industrialisation Du Logiciel - Introduction Et Bonnes Pratiques
Industrialisation Du Logiciel Introduction Et Bonnes Pratiques V1.4
Tour d'horizon des tests
Présentation des test driven development aka tdd
Bbd dans le flow nov.2012
Mockito - Design + tests par Brice Duteil
PHPTour Lyon 2014 - Conférence - Tests unitaires Je veux mes 80% de couvertur...
Présentation Alt.net - Tests unitaires automatisés
Keynote agile grenoble 2013
Pourquoi vous ne pouvez pas tester votre code
Tests de caractérisation : à l’assaut de votre code "Legacy" patrimonial [FR]
Pratiques de développement pour équipes Agile
Test driven development v0.2 20121221

Plus de CGI Québec Formation (14)

PDF
La culture produit au service du client
PPTX
Mythes et légendesKanban
PPTX
Gestion de performance : L'agilité à l'échelle
PPTX
La 5e Valeur Agile: La valeur plutôt que le suivi des coûts
PPTX
Démarrage express. Vers des démarrages de projets plus rapides et moins couteux
PPTX
Estimer les projets TI, même en Agile
PPTX
Large Scale Agile Transformation in Government: Field report
PDF
Atelier de simulation DevOps
PDF
Gestion de portefeuille performante et kanban stratégique - Version courte
PDF
Strategic Portfolio Management With Kanban
PPTX
Quelles sont vos attentes envers les ScrumMasters
PPTX
Semer la graine agile en entretien et évolution de systèmes
PPTX
Les bases de données, ces mal-aimées de l'Agilité!
PPTX
Mon Agilité est plus grosse que la tienne
La culture produit au service du client
Mythes et légendesKanban
Gestion de performance : L'agilité à l'échelle
La 5e Valeur Agile: La valeur plutôt que le suivi des coûts
Démarrage express. Vers des démarrages de projets plus rapides et moins couteux
Estimer les projets TI, même en Agile
Large Scale Agile Transformation in Government: Field report
Atelier de simulation DevOps
Gestion de portefeuille performante et kanban stratégique - Version courte
Strategic Portfolio Management With Kanban
Quelles sont vos attentes envers les ScrumMasters
Semer la graine agile en entretien et évolution de systèmes
Les bases de données, ces mal-aimées de l'Agilité!
Mon Agilité est plus grosse que la tienne

Tester du legacy code, mission impossible ?

  • 1. Tester du Legacy Code, mission impossible ?
  • 2. Bon après-midi, Ethan. • Votre mission, si vous l’acceptez, consiste à vous occuper d’un système informatique qui n’est pas nouveau ni trop vieux, mais qui n’a aucun tests automatisé. • Par contre, il est au cœur de plusieurs traitements d’affaires critiques. Vous allez avoir à ajouter de nouvelles fonctionnalités et a en faire l’entretien. • Nous avons observés les choses suivantes: – Classes de la logique d’affaire qui fait 32 000 lignes. – Une interface de 2000 lignes (incluant une ligne de commentaire par méthode) été créé récemment pour vous permettre d’introduire des tests. • Ce message s’auto-détruira dans 5 secondes …..
  • 3. Bon après-midi, Ethan. • Votre mission, si vous l’acceptez, consiste à vous occuper d’un système informatique qui n’est pas nouveau ni trop vieux, mais qui n’a aucun tests automatisé. • Par contre, il est au cœur de plusieurs traitements d’affaires critiques. Vous allez avoir à ajouter de nouvelles fonctionnalités et a en faire l’entretien. • Nous avons observés les choses suivantes: – Classes de la logique d’affaire qui fait 32 000 lignes. – Une interface de 2000 lignes (incluant une ligne de commentaire par méthode) été créé récemment pour vous permettre d’introduire des tests. • Ce message s’auto-détruira dans 5 secondes ….. MISSION
  • 4. Qui sommes-nous ? • Karl Métivier – Architecte Logiciel – Développeur – Coach Agile – Formateur • Yves St-Hilaire – Soutien au développement – Accompagnement, mentorat – Développement BI
  • 5. Histoire d’un système • On change notre processus, on passe à Scrum. • On nous demande d’ajouter des tests unitaires automatisés au code existant. – Oups, le système n’a pas été prévu pour cela… • Comment avoir le temps pour cela ? – Réunion pour discuter des bogues courants. – Documentation à mettre à jour. • Au final, problème de dette technique.
  • 7. Définitions pour le Legacy Code • Du code Legacy, c’est du code: – sans tests unitaires - Michael Feathers – plus vieux que ceux qui y travaillent – modifications en mode « patchage » – nécessitant un guide du marais pour s’y retrouver! • Enfreint constamment les principes SOLID • On n’ose pas y toucher. • Et les Legacy Systems ?
  • 8. Code « Legacy » Quand vous avez à travailler avec ça, c’est quoi votre feeling ?
  • 9. Pourquoi est-on pognés avec ça ? • Délais courts de développement • Plusieurs personnes y sont passées • Conception Legacy? –Architecture identique au dossier fonctionnel • Peu d’efforts alloués pour l’amélioration –Le système fonctionne, on n’y investit rien
  • 10. Quel est le problème au juste ?
  • 12. La conception n’est pas conçue pour les tests
  • 14. Code «pas propre» et bien d’autres
  • 15. Le dilemme du refactoring • Pour faire du refactoring, on doit avoir des tests • Pour mettre en place des tests, on doit refactoriser.
  • 16. Tester le Legacy Code: 1 - Comment le faire ?
  • 17. Cas 1 – Classe sans injection de dépendances • Pas de possibilité d’injecter un mock • Plusieurs appelants l’utilisent, souvent on ne peut les modifier
  • 18. Cas 1 – Classe sans injection de dépendances Comment ? • Pour la classe qu’on veut mocker : – Ajout d’une interface • À la classe à tester : – Ajout d’un constructeur permettant l’injection – On lui injectera l’instance à utiliser, ou une Factory • Les appelants ne sont pas impactés • On permet l’injection, mais les appelants existants ne l’utilisent pas
  • 19. Cas 1 – Ajout d’injection – Comment public class MyClass { private IFileReader reader; public MyClass(string fileName) { // original code // ... reader = new MyFileReader(fileName); } public MyClass(IFileReader injectedReader) { // original code // ... reader = injectedReader; } }
  • 20. Cas 1b – Classe sans injection de dépendances Comment ? • Autre technique : Patron « Test Specific Subclass » • Classe à mocker : ajout d’une interface à la classe • Classe à tester : – Ajout d’une méthode virtuelle « ObtenirInstanceClasseAppelee » • Dans le projet de test : – Hériter de la classe à tester – Implémenter notre propre « ObtenirInstanceClasseAppelee »
  • 21. Cas 1b – Test specific subclass – Comment? public class MyClass { protected int someProtectedInfo = 42; private IFileReader reader; public MyClass(string fileName) { reader = GetReader(fileName); } protected virtual IFileReader GetReader(string fileName) { return new MyFileReader(fileName); }} public class MyClassSpecificSubclass : MyClass { public IFileReader InsertMockHere; public MyClassSpecificSubclass(IFileReader aReader) { InsertMockHere = aReader; } protected override IFileReader GetReader(string fileName) { return InsertMockHere; } public int GetInternalInfo() { return someProtectedInfo; }}
  • 22. Cas 2 – La classe iceberg • Reconnaissable facilement – Grosse • Milliers, dizaines de milliers de lignes – Peu de méthodes publiques • Comptées sur une seule main • C’est quoi le problème? – Grande complexité cyclomatique – Interdépendances entre les méthodes – Donc difficile à tester
  • 23. Cas 2– La classe iceberg – Comment? • Identifier les différentes responsabilités – Noms de méthodes – #Region ou zones de commentaires • Refactoriser en plusieurs classes • Si impossible : – Identifiez les méthodes qui seraient publiques avec un refactoring – Changer la visibilité et testez ces méthodes
  • 24. Cas 2– La classe iceberg – Exemple (classe simplifiée!)
  • 25. Cas 3 – Méthode statique • Une méthode statique, l’équivalent d’un singleton • Une seule version possible pour tout le système – Donc pas mockable • Pas un problème pour la tester • Mais un véritable problème pour tester les méthodes qui l’appellent
  • 26. Cas 3 – Méthode statique – Comment? • Ajout d’une interface à la classe • Ajout de méthodes d’instance correspondant aux méthodes statiques – DRY : la méthode d’instance peut appeler la méthode statique! – Les appelants ne sont pas affectés • Éventuellement on pourra enlever complètement les méthodes statiques
  • 27. Cas 3 – Méthode statique – Code public class ClassUnderTest { public void MethodUnderTest() { // ... var number = AnotherClass.GetNumber(); if (number > 0) { } else { } // ... } } public class AnotherClass { public static int GetNumber() { return 4; } }
  • 28. Cas 3 – Méthode statique – Code public class ClassUnderTest { private IAnotherClass _anotherClass; public ClassUnderTest() { _anotherClass = new AnotherClass(); } public ClassUnderTest(IAnotherClass anotherClass) { _anotherClass = anotherClass; } public void MethodUnderTest() { // ... var number = _anotherClass.GetNumber(); if (number > 0) { } else { } // ... } } public class AnotherClass: IAnotherClass { public static int GetNumber() { return 4; } int IAnotherClass.GetNumber() { return AnotherClass.GetNumber(); } }
  • 29. Mais en avez-vous vraiment besoin ? • Parfois, l’ajout de tests unitaires demande beaucoup d’efforts pour peu de gains • Évaluer d’autres opportunités – CodedUI / Selenium – Tests intégrés, mocker uniquement les données – Tests comparatifs • Pas toujours les meilleures pratiques, mais faut s’adapter au contexte!
  • 30. Comment le BDD m'a aidé dans mon débogage • Partir d’un cas d’utilisation (déjà implémenté) et le descendre en étape BDD du début (contrôleur UI), passer par le service et aboutir dans une BD en mémoire • C’est long • On vérifie toutes les dépendances et on traverse toutes les couches • C’est long, mais après coup notre compréhension du code s’est vraiment améliorée • En plus, le test BDD reste et peut être rejoué !
  • 31. État d’esprit pour déboguer de Legacy Code • Voir le code comme une scène de crime • Faire un profil de l’agresseur (ou de ce qui cause le problème) • Analyser les hot-spots • Calculer la complexité • Faire la dissection de l’architecture • Cartographier une carte de connaissances de votre système • Impact sur l’existant
  • 32. Tester le Legacy Code: 2 - Comment avoir le droit ?
  • 34. C’est impossible d’en faire chez nous car… • Nous autres, c'est différent • On a un système de mission critique à l'entreprise • Nos utilisateurs ont le contrôle et le budget • Notre système est très complexe • On a des données nominatives • …
  • 35. C’est notre devoir d’être professionnel Du code propre n’apparaît pas de lui-même: • Vous avez à le produire • Vous avez à le maintenir • Vous en faites un engagement professionnel
  • 36. Combattre le résistance en discutant • La plupart des gestionnaires défendent leurs échéanciers et les requis avec passion. – Cela fait partie de leurs responsabilités. • Votre responsabilité : – Défendre également le code avec passion. • Ayez le courage de dire la vérité et de travailler pour arriver à un terrain d’entente. • Discuter avec votre PO ou votre chef d’équipe. Il devrait être sensible à la qualité produite. Donc de supporter l’équipe quand il sent qu’un refactoring est nécessaire.
  • 37. Il faut alors être stratégique • Cela ne donne pas grand chose de travailler sur du code qui va bien et qui n’a pas de problème régulièrement. Don’t fix it, if it’s not broken. • Trouver les points chauds de votre système: – Bogues réguliers – Difficiles à travailler – Modification à faire prochainement – Logique d’affaires importante • Progresser par la technique des petits pas.
  • 38. Bien évaluer Valeur de cet investissement : • Potentiel • Bloquant actuel • Criticité du système • Nombre de personnes impactées • Durée de vie du système • Refonte prévue?
  • 39. La résistance peut donc être combattue • C’est souvent le premier pas le plus difficile. • Ne pas oublier : – Être stratégique – Évaluer le tout • Y aller un test à la fois: – Et son Refactoring de code qui le suit.
  • 40. En fait, on en revient à la transparence Le premier pilier de l’agilité!
  • 41. 3. Comment tester du Legacy Code au jour le jour et s’en prémunir?
  • 42. Comprendre le code • Les tests nous apportent une façon de comprendre le code. • D’une certaine manière, les tests nous font travailler dur pour arriver à cette compréhension. • Il est facile de faire des tests en présence d’une bonne conception.
  • 43. Ne pas hésiter à utiliser des outils modernes • Legacy != outils désuets • Exemples : – Intégration continue – Dernière version de l’IDE – Dernières versions des librairies et frameworks – Système Legacy dans Docker
  • 44. Ne pas oublier les bases • OOP • Clean Code • Maîtrisez et appliquez les principes SOLID • Boy Scout Rule • Agile Modeling (Scott Ambler)
  • 45. Se prémunir contre le Legacy Code à la base • Les développeurs doivent demander Quoi, Pourquoi et pour Qui avant de trouver le Comment. • Ce n’est pas aux analystes et utilisateurs de leur dire le Comment. • On veut savoir du client/PO qu’est-ce qu’ils veulent, pourquoi ils le veulent et pour qui cela va être utile.
  • 46. Faire la conception en équipe • Les meilleures conceptions sont effectuées en équipe, et non par une seule personne. • La compréhension de l’architecture ainsi que son adoption est répandue dans toute l’équipe. • Pourquoi s’en passer ?
  • 47. Ou du Mob Programming ! • Approche où l’équipe complète (client, analyste et PO aussi) travaille sur la même chose : – Au même endroit – En même temps – Sur le même ordinateur • Un peu similaire au pair programming
  • 48. En résumé, nous avons vu… • C’est quoi du Legacy Code • Comment faire pour le tester • Comment affronter la résistance • Comment s’en prémunir au jour le jour
  • 49. Alors, tester du du Legacy Code, • Met à l’épreuve et renforce nos habilités en: – Programmation Orientée-Objet – Conception & Architecture • Offre un challenge qui peut donc être instructif et amusant ! • Nous rend plus professionnel en bout de ligne.
  • 50. Comment vous en sortez-vous avec le Legacy Code ?
  • 51. Références 1/2 • Podcast Hanselminutes 2016-08-05 « Learning to love Legacy Code with Andrea Goulet from CorgiByte » – http://hanselminutes.com/539/learning-to-love-legacy-code- with-andrea-goulet-from-corgibytes • Patron « Test Specific Subclass » – http://xunitpatterns.com/Test-Specific%20Subclass.html • XKCD Goto – https://xkcd.com/292/
  • 52. Autres références • Lectures suggérées • Beaucoup de connaissances et d’information sur le ‘net
  • 53. Pour nous rejoindre • Karl Métivier – Courriel: [email protected] – LinkedIn: https://www.linkedin.com/in/karlmetivier/fr – Twitter: @karlmet – Blogue: https://excellenceagile.com/ • Yves St-Hilaire – Courriel: [email protected] – LinkedIn: www.linkedin.com/in/yves-st-hilaire – Twitter: @sthiy