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 full-size 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 full-size slide

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

    View full-size slide

  4. Formations Mentorat Diagnostics Conférences

    View full-size slide

  5. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  8. • 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  15. Pourquoi ne pas
    revitaliser
    votre code?

    View full-size slide

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

    View full-size slide

  17. Graduellement,
    tout en produisant
    de la valeur

    View full-size slide

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

    View full-size slide

  19. Test de
    caractérisation

    View full-size slide

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

    View full-size slide

  21. 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 full-size slide

  22. 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 full-size slide

  23. 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 full-size slide

  24. 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 full-size slide

  25. 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 full-size slide

  26. 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 full-size slide

  27. 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 full-size slide

  28. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  32. • 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  37. 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 full-size slide

  38. 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 full-size slide

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

    View full-size slide

  40. 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 full-size slide

  41. Le défi moderne: la
    maintenabilité

    View full-size slide

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

    View full-size slide

  43. 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 full-size slide

  44. 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 full-size slide

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

    View full-size slide

  46. 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 full-size slide