Slide 1

Slide 1 text

& 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

Slide 2

Slide 2 text

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…

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

4 Qui sommes-nous ? Pascal Roy Ing., PSM, CSM, PMP Félix-Antoine Bourbonnais B.ing., PSM, M.Sc.

Slide 5

Slide 5 text

Formations Mentorat Diagnostics Conférences

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Suis-je seul à avoir du Legacy Code ?

Slide 9

Slide 9 text

C’est du code difficile à faire évoluer. Peu importe son âge ou la raison. Qu’est-ce que du Legacy Code ?

Slide 10

Slide 10 text

• 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…

Slide 11

Slide 11 text

Du code sans tests Michael Feathers, Working Effectively with Legacy Code

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Deux grandes approches… Que faire avec mon code Legacy ?

Slide 14

Slide 14 text

La peur : le pire ennemi du développement logiciel 14

Slide 15

Slide 15 text

Tanné de stresser pour une livraison, de déboguer, d’avoir peur de briser? 15

Slide 16

Slide 16 text

S.v.p. donnez- moi un nouveau projet !@/$%!/%

Slide 17

Slide 17 text

La descente aux enfers Legacy Code Pas de test Pas de réusinage Patches

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

Pourquoi ne pas revitaliser votre code?

Slide 20

Slide 20 text

Bien outillé, vous pouvez rénover !

Slide 21

Slide 21 text

Graduellement, tout en produisant de la valeur

Slide 22

Slide 22 text

Sélectionnez votre prochaine « Story » et commencez vos paiements de dette!

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

Test de caractérisation

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

Un test de caractérisation est une description du comportement actuel d’un bout de code. - Michael Feathers

Slide 27

Slide 27 text

C’est un briseur de PEUR ! Pour… Comprendre et documenter ce que fait le code Empêcher la régression lors du réusinage +

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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?

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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 ? ?

Slide 34

Slide 34 text

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 ? ?

Slide 35

Slide 35 text

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 ? ?

Slide 36

Slide 36 text

Attention aux « tant qu’à y être » ! Ciblez uniquement ce que vous voulez modifier.

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

On n’a pas le temps de faire ça ?!?

Slide 39

Slide 39 text

Combien de temps ça prend pour comprendre un bout de code Legacy avant de le modifier?

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

• 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?

Slide 42

Slide 42 text

Est-ce qu’entourer mon application avec des tests bout-en-bout peut m’aider à caractériser ?

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

Le réusinage (refactoring) n’est pas une petite refonte!

Slide 45

Slide 45 text

Pourquoi les gestionnaires/clients/chargés de projet ont-ils si peur du réusinage ?

Slide 46

Slide 46 text

Attention au réusinage en Big Bang ! 46

Slide 47

Slide 47 text

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 ?!?

Slide 48

Slide 48 text

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…

Slide 49

Slide 49 text

C’est le changement à faire qui guide notre intervention

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

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 ?

Slide 52

Slide 52 text

Le défi moderne: la maintenabilité

Slide 53

Slide 53 text

La pourriture du code n’est pas une « loi naturelle »

Slide 54

Slide 54 text

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!

Slide 55

Slide 55 text

Image de http://beinweb.fr/wp-content/uploads/2014/04/boite-a-outils-entrepreneurs.jpg Le test de caractérisation… Ajoutez-le à votre boîte à outils!

Slide 56

Slide 56 text

La « patrimonialite », ça se soigne !

Slide 57

Slide 57 text

Merci .

Slide 58

Slide 58 text

Site elapsetech.com Twitter @fbourbonnais Courriel [email protected] [email protected] 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