SlideShare une entreprise Scribd logo
1  sur  58
Télécharger pour lire hors ligne
&
FÉLIX-ANTOINE
BOURBONNAIS
B.ING., M.SC, PSM
Version: Mai 2017 (DEV)
Tests de caractérisation :
à l’assaut de votre
code « Legacy » patrimonial
PASCAL ROY
ING., CSM, PSM, PMP
Imaginez du code patrimonial
(Legacy)…
Imaginez un outil qui permettrait
à la fois d’explorer ce que le code
fait réellement et de réusiner ce
vieux code…
4
Qui sommes-nous ?
Pascal Roy
Ing., PSM, CSM, PMP
Félix-Antoine Bourbonnais
B.ing., PSM, M.Sc.
Formations Mentorat Diagnostics Conférences
Conférenciers
Formateurs
Mentors
Tech.
Équipe &
Affaires
Gestion
TDD
Architecture
évolutive
Essais
automatisés
DDD
…
Scrum
QA Agile
Gestion de
projets
Agilité
BDD
> Nous sommes
Conseils
stratégiques
> Spécialités
Suis-je seul à avoir
du Legacy Code ?
C’est du code difficile à
faire évoluer.
Peu importe son âge ou la raison.
Qu’est-ce que du Legacy Code ?
• Du code écrit par d’autres
• Du code que plus personne ne veut toucher
• Du code qui n’est plus supporté par ceux qui l’ont écrit
• Du code qui pourrait être réécrit en utilisant de meilleures pratiques de
code, d’outils ou de langages
• ...
Quelques autres définitions possibles…
Du code sans tests
Michael Feathers,
Working Effectively with Legacy Code
Deux grandes
approches…
Que faire avec mon code Legacy ?
La peur : le pire ennemi du
développement logiciel
14
Tanné de stresser pour une
livraison, de déboguer, d’avoir
peur de briser?
15
S.v.p. donnez-
moi un nouveau
projet !@/$%!/%
La descente aux enfers
Legacy Code Pas de test
Pas de
réusinage
Patches
Pourquoi ne pas
revitaliser
votre code?
Bien outillé, vous
pouvez rénover !
Graduellement,
tout en produisant
de la valeur
Sélectionnez votre prochaine
« Story » et commencez vos
paiements de dette!
Test de
caractérisation
Un test de caractérisation est une description du
comportement actuel d’un bout de code.
- Michael Feathers
C’est un briseur de PEUR !
Pour…
Comprendre et
documenter ce
que fait le code
Empêcher la
régression lors
du réusinage
+
1. Identifier et isoler un bout de code à modifier ou à analyser
2. Écrire un test qui passe par le bout de code avec une assertion qui
échouera
3. Exécuter le test et le laisser vous dire quel est le comportement actuel
4. Changer votre assertion et le nom du test pour tenir compte du
comportement actuel
5. Répéter…
La mécanique d’écriture d’un test de caractérisation
public class SalesUtil {
double BQ = 1000.0;
double BCR = 0.20;
double OQM1 = 1.5;
double OQM2 = OQM1 * 2;
public double calculate(double tSales) {
if (tSales <= BQ) {
return tSales * BCR;
} else if (tSales <= BQ * 2) {
return (BQ) * BCR + (tSales - BQ) * BCR * OQM1;
} else {
return (BQ) * BCR +
(tSales - BQ) * BCR * OQM1 +
(tSales - BQ * 2) * BCR * OQM2;
}
}
}
http://s3.amazonaws.com/giles/demons_010609/wtfm.jpg
Un exemple simple de code patrimonial?
WTF?
WTF?
WTF?
public class SalesUtil {
double BQ = 1000.0;
double BCR = 0.20;
double OQM1 = 1.5;
double OQM2 = OQM1 * 2;
public double calculate(double tSales){
if (tSales <= BQ) {
return tSales * BCR;
} else if (tSales <= BQ * 2) {
return (BQ) * BCR +
(tSales - BQ) * BCR * OQM1;
} else {
return (BQ) * BCR +
(tSales - BQ) * BCR * OQM1 +
(tSales - BQ * 2) * BCR * OQM2;
}
}
}
@Test
public void test… {
assert(...)
}
Étape 1: identifier un bout de code
1
?
2
? ?
1
2
public class SalesUtil {
double BQ = 1000.0;
double BCR = 0.20;
double OQM1 = 1.5;
double OQM2 = OQM1 * 2;
double calculate(double tSales) {
if (tSales <= BQ) {
return tSales * BCR;
} else if (tSales <= BQ * 2) {
return (BQ) * BCR +
(tSales - BQ) * BCR * OQM1;
} else {
return (BQ) * BCR +
(tSales - BQ) * BCR * OQM1+
(tSales - BQ*2)*BCR * OQM2;
}
}
}
@Test
public void testCalculate() {
assertEquals(
0.0,
SalesUtil.calculate(1000.0)
);
}
Étape 2: écrire une assertion qui ne passe pas
1
?
2
? ?
1
2
public class SalesUtil {
double BQ = 1000.0;
double BCR = 0.20;
double OQM1 = 1.5;
double OQM2 = OQM1 * 2;
double calculate(double tSales) {
if (tSales <= BQ) {
return tSales * BCR;
} else if (tSales <= BQ * 2) {
return (BQ) * BCR +
(tSales - BQ) * BCR * OQM1;
} else {
return (BQ) * BCR +
(tSales - BQ) * BCR * OQM1 +
(tSales - BQ * 2) * BCR * OQM2;
}
}
}
@Test
public void testCalculate() {
assertEquals(
0.0,
SalesUtil.calculate(1000.0)
);
}
Étape 3: exécuter le test
+ trouver le comportement actuel
> junit.framework.AssertionFailedError:
expected:<0.0> but was:<200.0>1
?
2
? ?
public class SalesUtil {
double BQ = 1000.0;
double BCR = 0.20;
double OQM1 = 1.5;
double OQM2 = OQM1 * 2;
double calculate(double tSales) {
if (tSales <= BQ) {
return tSales * BCR;
} else if (tSales <= BQ * 2) {
return (BQ) * BCR +
(tSales - BQ) * BCR * OQM1;
} else {
return (BQ) * BCR +
(tSales - BQ) * BCR * OQM1+
(tSales – BQ*2)*BCR * OQM2;
}
}
}
@Test
public void lessThanBaseQuota_useBaseCommissionRate()
{
assertEquals(
200.0,
SalesUtil.calculate(1000.0)
);
}
Étape 4: Remplacer par le comportement découvert
1
2
1
200
2
? ?
public class SalesUtil {
double BQ = 1000.0;
double BCR = 0.20;
double OQM1 = 1.5;
double OQM2 = OQM1 * 2;
double calculate(double tSales) {
if (tSales <= BQ) {
return tSales * BCR;
} else if (tSales <= BQ * 2) {
return (BQ) * BCR +
(tSales - BQ) * BCR * OQM1;
} else {
return (BQ) * BCR +
(tSales - BQ) * BCR*OQM1+
(tSales – BQ*2) * BCR*OQM2;
}
}
}
…
@Test
public void testCalculate() {
assertEquals(
0.0,
SalesUtil.calculate(2000.0)
);
}
Étape 5: Répéter
1
2
1
200
2
? ?
Attention aux « tant qu’à y être » !
Ciblez uniquement ce que vous voulez modifier.
On n’a pas le temps
de faire ça ?!?
Combien de temps ça prend pour
comprendre un bout de code Legacy
avant de le modifier?
• Spécification du
comportement requis
• Comportement connu
et nouveau code
• Permanent
• Spécification du
comportement actuel
• Code patrimonial,
comportement flou ou
perdu
• Temporaire
Test unitaire Caractérisation
How is a CT different?
Est-ce qu’entourer mon application avec
des tests bout-en-bout peut m’aider à
caractériser ?
Le réusinage (refactoring)
n’est pas une petite refonte!
Pourquoi les
gestionnaires/clients/chargés de
projet ont-ils si peur du réusinage ?
Attention au réusinage en Big Bang !
46
Une dépense
Big Bang
Risque très élevé
Pas de nouvelle valeur
Paiements réguliers (dette)
Étape par étape
Risque moindre
Produit de la valeur
Refaire Rénover / Revitaliser
Refonte ou réusinage ?!?
La stratégie
> on veut limiter les dommages
et focaliser sur l’objectif le plus
pressant
Comme la prise en charge d’un
patient dans une urgence…
C’est le changement à
faire qui guide notre
intervention
Cette présentation montre à comprendre et sécuriser votre patrimoine…
Maintenant, vous pouvez apprendre à rénover votre patrimoine:
• Sprout Methods/Classes
• Instance Delegator
• Extract to Method
• …
Maintenant… comment réusiner ?
Le défi moderne: la
maintenabilité
La pourriture du code
n’est pas une
« loi naturelle »
Although our first joy of programming may have
been intense, the misery of dealing with legacy code
is often sufficient to extinguish that flame.
Michael Feathers,
Working Effectively with Legacy Code
Le code patrimonial tue la flamme!
Imagede http://beinweb.fr/wp-content/uploads/2014/04/boite-a-outils-entrepreneurs.jpg
Le test de caractérisation…
Ajoutez-le à votre boîte à outils!
La « patrimonialite », ça se soigne !
Merci .
Site
elapsetech.com
Twitter
@fbourbonnais
Courriel
fbourbonnais@elapsetech.com
pascalroy@elapsetech.com
LinkedIn
linkedin.com/in/fbourbonnais/fr
ca.linkedin.com/in/roypa
conferences.elapsetech.com
Toutes nos présentations
conferences.elapsetech.com
/legacy-tests-caracterisation
Diapositives et références
Félix-Antoine Bourbonnais
Pascal Roy

Contenu connexe

Similaire à Tests de caractérisation : à l’assaut de votre code "Legacy" patrimonial [FR]

CocoaHeads Toulouse - Xcode et les tests - Epitez
CocoaHeads Toulouse - Xcode et les tests - EpitezCocoaHeads Toulouse - Xcode et les tests - Epitez
CocoaHeads Toulouse - Xcode et les tests - EpitezCocoaHeads France
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logiciellecyrilgandon
 
Les nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneLes nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneMicrosoft
 
gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !Carles Sistare
 
gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!David Caramelo
 
Comment passer d'un POC en prod @ plusieurs milliards de rêquetes
Comment passer d'un POC en prod @ plusieurs milliards de rêquetesComment passer d'un POC en prod @ plusieurs milliards de rêquetes
Comment passer d'un POC en prod @ plusieurs milliards de rêquetesCarles Sistare
 
Optimisations et Performances d'un POC en prod @ plusieurs milliards de requê...
Optimisations et Performances d'un POC en prod @ plusieurs milliards de requê...Optimisations et Performances d'un POC en prod @ plusieurs milliards de requê...
Optimisations et Performances d'un POC en prod @ plusieurs milliards de requê...David Caramelo
 
Développer en natif avec C++11
Développer en natif avec C++11Développer en natif avec C++11
Développer en natif avec C++11Microsoft
 
Tester du legacy code, mission impossible ?
Tester du legacy code, mission impossible ?Tester du legacy code, mission impossible ?
Tester du legacy code, mission impossible ?CGI Québec Formation
 
Agile - Les stories INVEST, 3C et SMART
Agile - Les stories INVEST, 3C et SMARTAgile - Les stories INVEST, 3C et SMART
Agile - Les stories INVEST, 3C et SMARTSébastien GAUDIN
 
Voodoo.io NodeJS Meetup - November 13
Voodoo.io NodeJS Meetup - November 13Voodoo.io NodeJS Meetup - November 13
Voodoo.io NodeJS Meetup - November 13Aymeric Roffé
 
2024-01 - slides du meetup devops aix-marseille
2024-01 - slides du meetup devops aix-marseille2024-01 - slides du meetup devops aix-marseille
2024-01 - slides du meetup devops aix-marseilleFrederic Leger
 

Similaire à Tests de caractérisation : à l’assaut de votre code "Legacy" patrimonial [FR] (20)

Fusion io
Fusion ioFusion io
Fusion io
 
ParisJUG-2022-v0.4.pdf
ParisJUG-2022-v0.4.pdfParisJUG-2022-v0.4.pdf
ParisJUG-2022-v0.4.pdf
 
CocoaHeads Toulouse - Xcode et les tests - Epitez
CocoaHeads Toulouse - Xcode et les tests - EpitezCocoaHeads Toulouse - Xcode et les tests - Epitez
CocoaHeads Toulouse - Xcode et les tests - Epitez
 
Tour d'horizon des tests
Tour d'horizon des testsTour d'horizon des tests
Tour d'horizon des tests
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logicielle
 
Présentation de jBPM 3.1
Présentation de jBPM 3.1Présentation de jBPM 3.1
Présentation de jBPM 3.1
 
Les nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneLes nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ Moderne
 
gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !
 
gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!
 
Retour d'expérience sur PowerShell
Retour d'expérience sur PowerShellRetour d'expérience sur PowerShell
Retour d'expérience sur PowerShell
 
Comment passer d'un POC en prod @ plusieurs milliards de rêquetes
Comment passer d'un POC en prod @ plusieurs milliards de rêquetesComment passer d'un POC en prod @ plusieurs milliards de rêquetes
Comment passer d'un POC en prod @ plusieurs milliards de rêquetes
 
Optimisations et Performances d'un POC en prod @ plusieurs milliards de requê...
Optimisations et Performances d'un POC en prod @ plusieurs milliards de requê...Optimisations et Performances d'un POC en prod @ plusieurs milliards de requê...
Optimisations et Performances d'un POC en prod @ plusieurs milliards de requê...
 
Introduction à MacRuby
Introduction à MacRubyIntroduction à MacRuby
Introduction à MacRuby
 
Développer en natif avec C++11
Développer en natif avec C++11Développer en natif avec C++11
Développer en natif avec C++11
 
Tester du legacy code, mission impossible ?
Tester du legacy code, mission impossible ?Tester du legacy code, mission impossible ?
Tester du legacy code, mission impossible ?
 
Agile - Les stories INVEST, 3C et SMART
Agile - Les stories INVEST, 3C et SMARTAgile - Les stories INVEST, 3C et SMART
Agile - Les stories INVEST, 3C et SMART
 
Voodoo.io NodeJS Meetup - November 13
Voodoo.io NodeJS Meetup - November 13Voodoo.io NodeJS Meetup - November 13
Voodoo.io NodeJS Meetup - November 13
 
2024-01 - slides du meetup devops aix-marseille
2024-01 - slides du meetup devops aix-marseille2024-01 - slides du meetup devops aix-marseille
2024-01 - slides du meetup devops aix-marseille
 
C# 7 - Nouveautés
C# 7 - NouveautésC# 7 - Nouveautés
C# 7 - Nouveautés
 
Urbaniser un SI pour 10 ans
Urbaniser un SI pour 10 ansUrbaniser un SI pour 10 ans
Urbaniser un SI pour 10 ans
 

Tests de caractérisation : à l’assaut de votre code "Legacy" patrimonial [FR]

  • 1. & FÉLIX-ANTOINE BOURBONNAIS B.ING., M.SC, PSM Version: Mai 2017 (DEV) Tests de caractérisation : à l’assaut de votre code « Legacy » patrimonial PASCAL ROY ING., CSM, PSM, PMP
  • 2. Imaginez du code patrimonial (Legacy)… Imaginez un outil qui permettrait à la fois d’explorer ce que le code fait réellement et de réusiner ce vieux code…
  • 3.
  • 4. 4 Qui sommes-nous ? Pascal Roy Ing., PSM, CSM, PMP Félix-Antoine Bourbonnais B.ing., PSM, M.Sc.
  • 7.
  • 8. Suis-je seul à avoir du Legacy Code ?
  • 9. C’est du code difficile à faire évoluer. Peu importe son âge ou la raison. Qu’est-ce que du Legacy Code ?
  • 10. • Du code écrit par d’autres • Du code que plus personne ne veut toucher • Du code qui n’est plus supporté par ceux qui l’ont écrit • Du code qui pourrait être réécrit en utilisant de meilleures pratiques de code, d’outils ou de langages • ... Quelques autres définitions possibles…
  • 11. Du code sans tests Michael Feathers, Working Effectively with Legacy Code
  • 12.
  • 13. Deux grandes approches… Que faire avec mon code Legacy ?
  • 14. La peur : le pire ennemi du développement logiciel 14
  • 15. Tanné de stresser pour une livraison, de déboguer, d’avoir peur de briser? 15
  • 16. S.v.p. donnez- moi un nouveau projet !@/$%!/%
  • 17. La descente aux enfers Legacy Code Pas de test Pas de réusinage Patches
  • 18.
  • 22. Sélectionnez votre prochaine « Story » et commencez vos paiements de dette!
  • 23.
  • 25.
  • 26. Un test de caractérisation est une description du comportement actuel d’un bout de code. - Michael Feathers
  • 27. C’est un briseur de PEUR ! Pour… Comprendre et documenter ce que fait le code Empêcher la régression lors du réusinage +
  • 28.
  • 29. 1. Identifier et isoler un bout de code à modifier ou à analyser 2. Écrire un test qui passe par le bout de code avec une assertion qui échouera 3. Exécuter le test et le laisser vous dire quel est le comportement actuel 4. Changer votre assertion et le nom du test pour tenir compte du comportement actuel 5. Répéter… La mécanique d’écriture d’un test de caractérisation
  • 30. public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; public double calculate(double tSales) { if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1 + (tSales - BQ * 2) * BCR * OQM2; } } } http://s3.amazonaws.com/giles/demons_010609/wtfm.jpg Un exemple simple de code patrimonial? WTF? WTF? WTF?
  • 31. public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; public double calculate(double tSales){ if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1 + (tSales - BQ * 2) * BCR * OQM2; } } } @Test public void test… { assert(...) } Étape 1: identifier un bout de code 1 ? 2 ? ? 1 2
  • 32. public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; double calculate(double tSales) { if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1+ (tSales - BQ*2)*BCR * OQM2; } } } @Test public void testCalculate() { assertEquals( 0.0, SalesUtil.calculate(1000.0) ); } Étape 2: écrire une assertion qui ne passe pas 1 ? 2 ? ? 1 2
  • 33. public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; double calculate(double tSales) { if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1 + (tSales - BQ * 2) * BCR * OQM2; } } } @Test public void testCalculate() { assertEquals( 0.0, SalesUtil.calculate(1000.0) ); } Étape 3: exécuter le test + trouver le comportement actuel > junit.framework.AssertionFailedError: expected:<0.0> but was:<200.0>1 ? 2 ? ?
  • 34. public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; double calculate(double tSales) { if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1+ (tSales – BQ*2)*BCR * OQM2; } } } @Test public void lessThanBaseQuota_useBaseCommissionRate() { assertEquals( 200.0, SalesUtil.calculate(1000.0) ); } Étape 4: Remplacer par le comportement découvert 1 2 1 200 2 ? ?
  • 35. public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; double calculate(double tSales) { if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR*OQM1+ (tSales – BQ*2) * BCR*OQM2; } } } … @Test public void testCalculate() { assertEquals( 0.0, SalesUtil.calculate(2000.0) ); } Étape 5: Répéter 1 2 1 200 2 ? ?
  • 36. Attention aux « tant qu’à y être » ! Ciblez uniquement ce que vous voulez modifier.
  • 37.
  • 38. On n’a pas le temps de faire ça ?!?
  • 39. Combien de temps ça prend pour comprendre un bout de code Legacy avant de le modifier?
  • 40.
  • 41. • Spécification du comportement requis • Comportement connu et nouveau code • Permanent • Spécification du comportement actuel • Code patrimonial, comportement flou ou perdu • Temporaire Test unitaire Caractérisation How is a CT different?
  • 42. Est-ce qu’entourer mon application avec des tests bout-en-bout peut m’aider à caractériser ?
  • 43.
  • 44. Le réusinage (refactoring) n’est pas une petite refonte!
  • 45. Pourquoi les gestionnaires/clients/chargés de projet ont-ils si peur du réusinage ?
  • 46. Attention au réusinage en Big Bang ! 46
  • 47. Une dépense Big Bang Risque très élevé Pas de nouvelle valeur Paiements réguliers (dette) Étape par étape Risque moindre Produit de la valeur Refaire Rénover / Revitaliser Refonte ou réusinage ?!?
  • 48. La stratégie > on veut limiter les dommages et focaliser sur l’objectif le plus pressant Comme la prise en charge d’un patient dans une urgence…
  • 49. C’est le changement à faire qui guide notre intervention
  • 50.
  • 51. Cette présentation montre à comprendre et sécuriser votre patrimoine… Maintenant, vous pouvez apprendre à rénover votre patrimoine: • Sprout Methods/Classes • Instance Delegator • Extract to Method • … Maintenant… comment réusiner ?
  • 52. Le défi moderne: la maintenabilité
  • 53. La pourriture du code n’est pas une « loi naturelle »
  • 54. Although our first joy of programming may have been intense, the misery of dealing with legacy code is often sufficient to extinguish that flame. Michael Feathers, Working Effectively with Legacy Code Le code patrimonial tue la flamme!
  • 55. Imagede http://beinweb.fr/wp-content/uploads/2014/04/boite-a-outils-entrepreneurs.jpg Le test de caractérisation… Ajoutez-le à votre boîte à outils!
  • 56. La « patrimonialite », ça se soigne !