Journal du mercredi 25 septembre 2024 à 18:28
Un ami m'a posé la question suivante :
Imaginez-vous face à un projet React avec des dépendances fortement obsolètes, fonctionnant sur une version de Node datant d’il y a cinq ans. En plus, il n’existe aucun test automatisé, qu'il s'agisse de tests unitaires ou d'intégration. Vous êtes contraint de réaliser cette mise à jour, car elle bloque les futurs développements et entraîne une accumulation excessive de dette technique. Quelle serait votre approche dans cette situation ?
- Affronter le problème de front : On prend le taureau par les cornes, on met tout à jour d’un coup, quitte à rencontrer des breaking changes ou des bugs non anticipés, que l’on corrigera rapidement (option rapide mais risquée).
- Prudence avant tout : On commence par ajouter des tests sur les parcours critiques, puis on met à jour les dépendances une par une, même si cela prend plus de temps (option lente mais sécurisée).
- Déléguer la décision : Ce n’est pas à moi de décider. Je présente ces options aux responsables et leur laisse la décision finale.
Avant de pouvoir répondre à cette question, j'ai besoin de déterminer la criticité business de cette application.
Est-ce que les décideurs acceptent que l'application puisse être en panne pendant 1 heure ? 1 jour ? 3 jours ? Ou aucune interruption n'est-elle tolérée ?
Si la réponse est "moins de 24 heures", alors je considère que l'application est critique.
Ensuite j'ai besoin de savoir si la mise à jour du projet peut être réaliser de manière iso-fonctionnelle (sans changement fonctionnel), sans changement d'User Interface et sans changement du modèle de donnée.
Si la réponse est positive, cela signifie qu'il sera facile de revenir à la version précédente en cas de problème, ce qui simplifie grandement le processus de refactoring.
Une de mes premières actions concrètes serait de "dockeriser" le projet pour faciliter son déploiement et permettre un retour rapide à une version antérieure si nécessaire.
Une autre question importante : d'autres développeurs interviendront-ils sur le projet pendant la période de refactoring ? Est-ce que des corrections de bugs ou de nouvelles fonctionnalités doivent être intégrées durant cette période ?
Si la réponse à l'une de ces questions est "oui", je recommande de dupliquer le projet dans deux dossiers distincts au sein d'un monorepo :
Pendant toute la durée du refactoring, les corrections de bugs et les nouvelles fonctionnalités devront être appliquées aux deux versions.
Dans tous les cas, pour ne pas perdre pied, j'essaierai de mettre à jour l'application petit à petit.
Je commencerai par essayer de mettre à jour toutes les versions mineures des packages.
Ensuite, j'essaierai de me renseigner sur les breaking changes des mises à jour majeures des packages.
Si l'application est critique, alors il est inacceptable que les utilisateurs découvrent eux-mêmes les bugs et doivent contacter le support pour signaler les problèmes.
Si l'application ne comporte aucun test, je suppose qu'elle est testée manuellement et que son périmètre fonctionnel reste limité.
L'une de mes premières actions serait de définir un ou plusieurs scénarios de tests manuels prioritaires, que je ferais valider par les décideurs.
Ensuite, je proposerai aux décideurs d'envisager le développement de quelques tests fonctionnels automatisés. Une décision rationnelle à ce sujet dépendrait du temps nécessaire pour effectuer ces tests manuellement et, encore une fois, de la criticité business de l'application.
Enfin, je mettrai en place un système de déploiement progressif, de type A/B testing, permettant de déployer la nouvelle version de l'application à un nombre très restreint d'utilisateurs dans un premier temps.
Si, d'un point de vue business, il est acceptable que les utilisateurs découvrent les bugs, alors je n'implémenterai pas de tests automatisés.
Je définirai tout de même quelques scénarios de tests manuels que le développeur seul exécutera.
Si cela ne demande pas trop de temps, je mettrai en place un système de déploiement progressif, tel que l'A/B testing, permettant de déployer la nouvelle version de l'application à un nombre restreint d'utilisateurs dans un premier temps.