Refactoring : la technique du Golden Master

La méthode du Golden Master vise à éviter les régressions lors d'un refactoring et repose sur la création préalable d'une trace de logs fonctionnels.
Publié le 14 septembre 2022Dernière mise à jour le 15 février 2025
Il fait beau, il fait frais ce matin, vous avez bien dormi et vous vous sentez d'attaque pour refactorer. Noble intention !
Il y a quelques refactorings sûrs, c'est-à-dire des modifications basées sur l'arbre syntaxique abstrait (AST). Ce sont des "low hanging fruits" qu'il faut cueillir, à supposer toutefois qu'un système de typage soit en place — friendly poke aux aficionados du JavaScript, parce que "le typage, c'est trop contraignant" : laissez-moi rire.
En dehors de ça… oui, ça nous démange de séparer les responsabilités de cette fonction/classe qui fait tout (God class).

De la difficulté d'écrire des tests de non-régression

Mais à partir de là, il faut faire très attention : derrière chaque action se cache une régression, tapie dans l'ombre, prête à bondir et qui ricane à l'idée de faire tomber la prod 😈👻
Comment les éviter ? Ça serait bien d'avoir un filet de sécurité. Et ça s'appelle ? Des tests. Fort bien, écrivons des tests, alors.
Sauf que ça n'est pas si simple : le code n'a pas été pensé pour être testable. Comment lire la valeur de cet état s'il n'est pas exposé ? Comment mocker cette dépendance, vu que rien n'est en place pour ça ?
Posons le problème : nous voulons "capturer" le comportement de l'application sans coupler les tests à l'implémentation, puisque cette dernière va changer.
Une façon de faire consisterait à parsemer le code de logs. Mais un log tel que
{ id: 171932, name: "Paul", balance: 1400, unit: "EUR", date: "31/10/2022"}
va rapidement poser problème, parce que ce log est le reflet du modèle et de l'implémentation actuels, que l'on cherche justement à refactorer.
Par contraste, un log tel que
Le solde du compte bancaire de Paul est de 1400€ au 31/10/2022
, exprimé en langage naturel et dans des termes purement métier, nous aidera beaucoup plus.
L'idée sera d'assurer la stabilité des logs au travers du refactoring. Et là, nous venons de réinventer la méthode du Golden Master.

Golden Master : figer des scénarios métiers à l'aide de logs fonctionnels

La méthode procède en 3 temps :
  1. Création du master, c'est-à-dire une piste de logs fonctionnels capturant le comportement de l'application de manière exhaustive. Le choix des scénarios métiers est donc déterminant. Cette étape requiert généralement plusieurs itérations, car elle est en même temps une phase de découverte de l'application. Durant cette phase, on s'aidera de la couverture de code, que l'on veut à 100%. Mais attention, la condition est nécessaire sans être suffisante : on peut avoir couvert le code à 100% par des tests sans pour autant avoir exploré tous les chemins d'exécution de l'application.
  2. Refactoring : bien sûr on ne part pas bille en tête dans un gros refactoring. On prend le temps d'explorer la codebase, pour ensuite procéder par petites touches. Cela s'appelle la Méthode Mikado . A l'issue de chaque refactoring, on rejoue l'ensemble des tests. Les logs fonctionnels ainsi générés sont comparés au master, et la moindre différence est le signe d'une régression. Durant cette étape, il n'est pas interdit d'écrire des tests propres à la nouvelle implémentation, voire de se laisser guider par les tests (Test-driven development ). Comprenez : "Faites-le !" 😁
  3. Suppression du master : ces tests sont par essence temporaires. Ils doivent être vus comme des échafaudages, que l'on démonte une fois le bâtiment construit. Nous avons pris soin de rajouter des tests unitaires et d'intégration pour la nouvelle implémentation, donc nous pouvons supprimer les tests du Golden Master sans rien perdre en couverture de code.
Voilà. Le Golden Master, c'est ça. Rien que ça, mais encore faut-il le faire. Ces méthodes de refactoring sont abordées en détail dans ma formation L'art du refactoring , mais dans tous les cas les maîtriser demande une bonne dose de pratique, alors… à vos claviers ! 💻