Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

Beaucoup d’entreprises sont aux prises avec une importante base de code patrimoniale (legacy). Elles savent qu’il faut s’y attaquer, mais elles ne savent pas par où commencer et abandonnent par découragement

Pas de tests → Difficulté à réusiner → Architecture mal adaptée
→ Difficulté à écrire des tests → “Patch” laide → Retour à la case départ → ... → Refonte obligatoire :(

Comment éviter le piège coûteux et extrêmement risqué de la refonte ? Pour briser ce cercle vicieux, il existe une forme de tests appelés “tests de caractérisation”. Voici une technique de “consolidation de dettes” techniques !

Dans cette présentation Félix-Antoine Bourbonnais et Pascal Roy d’Elapse Technologies vous présenteront pourquoi, comment, quand écrire et ne pas écrire ce type de tests.

Une démonstration dynamique avec du code typique qui vous permettra de voir en action l’écriture de tests de caractérisation, puis le réusinage (refactoring).

Voir:
http://conferences.elapsetech.com/legacy-tests-caracterisation/

More Decks by Félix-Antoine Bourbonnais

Other Decks in Technology

Transcript

  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

    View Slide

  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…

    View Slide

  3. View Slide

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

    View Slide

  5. Formations Mentorat Diagnostics Conférences

    View Slide

  6. 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

    View Slide

  7. View Slide

  8. Suis-je seul à avoir
    du Legacy Code ?

    View Slide

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

    View Slide

  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…

    View Slide

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

    View Slide

  12. View Slide

  13. Deux grandes
    approches…
    Que faire avec mon code Legacy ?

    View Slide

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

    View Slide

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

    View Slide

  16. S.v.p. donnez-
    moi un nouveau
    projet [email protected]/$%!/%

    View Slide

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

    View Slide

  18. View Slide

  19. Pourquoi ne pas
    revitaliser
    votre code?

    View Slide

  20. Bien outillé, vous
    pouvez rénover !

    View Slide

  21. Graduellement,
    tout en produisant
    de la valeur

    View Slide

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

    View Slide

  23. View Slide

  24. Test de
    caractérisation

    View Slide

  25. View Slide

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

    View Slide

  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
    +

    View Slide

  28. View Slide

  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

    View Slide

  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?

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  37. View Slide

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

    View Slide

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

    View Slide

  40. View Slide

  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?

    View Slide

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

    View Slide

  43. View Slide

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

    View Slide

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

    View Slide

  46. Attention au réusinage en Big Bang !
    46

    View Slide

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

    View Slide

  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…

    View Slide

  49. C’est le changement à
    faire qui guide notre
    intervention

    View Slide

  50. View Slide

  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 ?

    View Slide

  52. Le défi moderne: la
    maintenabilité

    View Slide

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

    View Slide

  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!

    View Slide

  55. 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!

    View Slide

  56. La « patrimonialite », ça se soigne !

    View Slide

  57. Merci .

    View Slide

  58. 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

    View Slide