Travailler avec le code hérité et 3 étapes pour le mettre à jour
Par Igor Kirilenko
19 octobre 2018
7 min lire
Travailler avec des codes hérités est une réalité quotidienne. Cependant, les lacunes dans les connaissances sur le code représentent des risques potentiels. Lisez la suite pour comprendre comment atténuer ces risques et mettre à jour votre ancien code.
Aller à la section
Lorsque vous traitez avec du code hérité, vous avez besoin d'un moyen durable de gérer le changement. Travailler avec du code hérité peut être un obstacle à Agile et DevOps, mais vous pouvez relever le défi en tirant parti des technologies appropriées.
Qu'est-ce que l'ancien code?
De nombreuses personnes utilisent le terme «code hérité» pour désigner simplement l'ancien code. Mais «ancien» et «héritage» signifient des choses différentes pour différentes personnes. Ici, j'utilise la définition du code hérité comme tout code existant dont l'équipe a une connaissance limitée.
La connaissance du code peut être incomplète pour plusieurs raisons, telles que:
- L'équipe a acquis un projet d'une autre partie de l'organisation.
- L'auteur original a quitté l'équipe et a pris connaissance du code avec lui.
- La fonctionnalité fournie par le code n'est plus une priorité commerciale et est restée inchangée, ce qui entraîne des détails oubliés sur le code.
Dans tous les cas, soyons clairs: le code hérité est la règle, pas l'exception. Une grande partie de l'infrastructure logicielle dans le monde fonctionne aujourd'hui sur du code hérité. La question est alors de savoir comment atténuer les risques associés au code hérité lorsque nous devons apporter un changement? Dans cet article de blog, je vais vous donner quelques solutions pour travailler efficacement avec le code hérité.
Webinaire: Meilleures pratiques pour atteindre les objectifs de couverture de code avec JUnit
Le code hérité est un obstacle à l'agilité et au DevOps
Le problème avec le code hérité n'est pas son âge - c'est que vous ne comprenez pas comment sa modification peut affecter les fonctionnalités existantes. Les lacunes dans les connaissances associées au code hérité peuvent devenir un obstacle si vous passez à une nouvelle méthodologie de développement, telle que Agile ou DevOps.
Agile et DevOps sont devenus les méthodologies dominantes pour la création de logiciels, car ils aident les équipes à itérer et publier rapidement les applications dès que les fonctionnalités commercialisables minimales sont prêtes. Des cycles de développement courts et fréquents sont la marque des méthodologies de développement itératif, mais ces approches ne laissent pas de place pour atténuer les résultats potentiellement problématiques lorsque vous traitez avec du code hérité. Essayer d'itérer rapidement sur du code que vous ne comprenez pas est susceptible d'introduire de nouveaux problèmes.
La réalité est que ces techniques sont beaucoup plus faciles à appliquer lors du démarrage de nouveaux projets. Pour les projets qui existent depuis un certain temps, les équipes travaillent généralement avec des systèmes qui impliquent du code hérité. Les développeurs peuvent ne pas savoir comment fonctionne la base de code existante, mais doivent tout de même corriger les défauts ou étendre les fonctionnalités sans introduire de nouveaux problèmes. Et même des changements superficiels ou apparemment mineurs peuvent avoir un impact significatif sur l'application.
Pourquoi la dette technique est importante (ou non)
Le jeu de développement logiciel consiste à équilibrer constamment la qualité du logiciel, le délai de mise sur le marché et le coût du développement. Dans la plupart des cas, nous faisons des compromis pour atteindre les objectifs commerciaux en fonction de ce qui se passe sur le marché. Au fil du temps, nous accumulons des dettes techniques.
Qu'est-ce que la dette technique ?
Dette technique est le coût de l'atténuation du risque associé à la mise en œuvre d'une solution imparfaite afin d'atteindre votre objectif de délai de mise sur le marché ou de coût de développement. (Par exemple, renoncer aux mises à niveau d'une bibliothèque parce que cela aurait retardé la publication représente une dette technique sous la forme de temps qu'il faudra pour mettre à jour la bibliothèque ultérieurement.)
Dans de nombreux cas, les bases de code héritées héritées sont lourdes de dettes techniques sous la forme d'une faible testabilité, d'une faible couverture, d'un code trop complexe, etc. La dette technique peut alourdir l'application de nouvelles pratiques de développement logiciel car les équipes sont constamment confrontées à la question de savoir s'il faut y remédier. la dette.
Faut-il s'inquiéter de la dette technique ?
Pour mettre les choses en perspective, chaque application a une dette technique et de nombreuses organisations peuvent investir des ressources importantes pour la rembourser sans en tirer aucun avantage substantiel. En fin de compte, la décision d'investir des ressources dans le remboursement de la dette technique dépend des parties de votre application que vous prévoyez de modifier. Mais vous ne le saurez pas à moins que vous ne commenciez à prendre quelques mesures supplémentaires (j'y reviendrai dans un instant).
Augmentation de la couverture sur le code hérité
Lorsque les organisations héritent d'une base de code héritée à gérer, elles adoptent souvent une politique de couverture qui les aide à créer une base de référence pour un nouveau développement. Le code hérité est déjà sur le terrain et est censé fonctionner, donc l'accent est mis sur la qualité du nouveau code. Afin de se conformer à la politique de couverture, de nombreuses organisations augmentent la couverture du code hérité par tous les moyens nécessaires. Une faible couverture fait baisser les paramètres globaux, ce qui rend difficile la mesure précise de la couverture pour votre nouveau développement. Si vous savez que vous travaillez avec du code hérité bien couvert, les métriques globales du projet peuvent indiquer si le nouveau développement évolue dans la bonne direction.
La justification sous-jacente de cette stratégie est solide, mais le problème est que les organisations génèrent aveuglément des tests afin de se conformer à leur politique de couverture. En conséquence, le projet est chargé de tests non maintenables qui donnent une fausse impression de la qualité du logiciel. Si vous ne prévoyez pas de toucher au code ou si vous n'êtes pas concerné par la maintenabilité ou la qualité des tests, vous pouvez utiliser l'un des nombreux outils de génération de tests sur le marché qui peuvent vous aider à atteindre cet objectif.
Créez des tests Java significatifs et maintenables
Pour être clair, je ne préconise pas de générer aveuglément des tests. À la place, utilisez un outil qui vous aide à créer rapidement des tests significatifs pour couvrir votre ancien code Java. Jtest Parasoft fournit une interface pointer-cliquer qui offre aux développeurs un processus de création de test automatique basé sur le code existant. La suite de régression qui en résulte est significative, maintenable et extensible.
Fitch offre une couverture et une qualité de code élevées pour les applications de microservices
Les 3 étapes pour mettre à jour votre ancien code
Plutôt que d'essayer de travailler au niveau macro, créez une base de référence et restreignez la portée de vos activités de qualité aux zones de code affectées par vos modifications planifiées. Après avoir pris des mesures pour évaluer la portée et l'état du code, vous devez créer des tests qui capturent le comportement actuel afin que l'équipe puisse comprendre comment les modifications peuvent affecter les fonctionnalités existantes.
Vous pouvez ensuite tirer parti d'une gamme de technologies qui vous aident à collecter des analyses lorsque vous refactorisez le code hérité et vous assurez que votre investissement dans les changements de code améliore la sûreté, la sécurité et la fiabilité des systèmes hérités.
1. Définissez votre périmètre.
Comprendre comment les modifications affectent le comportement du système nécessite au moins un point de données. Commencez par choisir une version de base et commencez à suivre les métriques à l'avenir. Définissez votre portée et examinez trois caractéristiques du code hérité:
- Combien de violations d'analyse statique avez-vous et quelle est leur gravité? Vous devez comprendre combien de défauts potentiels sont intégrés au code.
- Quelle est votre couverture de test actuelle? Une faible couverture représente un risque potentiel associé au changement.
- Combien de nettoyage sera nécessaire? Des mesures supplémentaires, telles que la complexité, les commentaires, etc., peuvent fournir une perspective sur l'état de la qualité du logiciel.
Parasoft fournit une puissante plate-forme d'analyse pour capturer, corréler et signaler les violations de l'analyse de code, les résultats des tests, l'analyse de la couverture et d'autres données de qualité logicielle. La plate-forme va au-delà des rapports statiques - elle applique également une analyse supplémentaire pour vous aider à identifier les parties de l'application affectées par le changement.
En tirant parti du concept de groupes de ressources, vous pouvez identifier un ensemble spécifique de fichiers ou de répertoires et la couverture de l'étendue, les violations d'analyse statique et les données de mesure de ces ressources spécifiques. Ces informations vous aident à créer une ligne de base pour les zones de la base de code avant d'apporter des modifications dans ces parties du code.
2. Capturez le comportement.
Armé d'un point de données initial, l'étape suivante consiste à commencer à capturer le comportement actuel du système en créant des tests. La création d'une suite de régression de haute qualité capture non seulement le comportement existant, mais également la couverture, qui sert de filet de sécurité pour s'assurer que les modifications n'interrompent pas la fonctionnalité.
Parasoft Jtest est parfaitement adapté à cette tâche car il vous permet de créer une ligne de base de tests JUnit en masse, y compris des assertions, sur la base du code existant. Jtest inclut également la possibilité de créer des tests qui accèdent directement aux méthodes privées lorsque le code hérité n'a pas été initialement écrit avec la testabilité à l'esprit.
Il est préférable d'étendre la couverture avec des tests significatifs. Au cours de l'analyse de l'écart de couverture, Jtest identifie les tests existants qui peuvent être clonés et mutés pour atteindre les parties non testées du code. Beaucoup de travail a été consacré à la création de ces tests existants, et la fonctionnalité de clonage et de mutation de Jtest augmente le retour sur votre investissement dans la création de tests.
Vous devez vous efforcer d'obtenir le niveau de couverture le plus élevé possible, mais dans la plupart des cas, atteindre une couverture de 100% sur l'ensemble de la base de code n'est pas pratique. Nous discuterons une technique supplémentaire que vous pouvez appliquer comme filet de sécurité pour assurer une couverture sur le code modifié un peu plus tard.
Lorsque vous avez une bonne couverture d'un point de vue fonctionnel, vous pouvez commencer à apporter des modifications et à modifier les tests au fur et à mesure.
3. Améliorez le code hérité isolé.
Une fois le comportement du système capturé, vous pouvez commencer à corriger les violations, à traiter les PR ou à appliquer les modifications sur lesquelles vous souhaitez vous concentrer avec un risque minimal de rupture des fonctionnalités existantes. Parasoft peut vous aider à gérer la dette technique existante et à placer les données, telles que les violations d'analyse statique, dans des flux de travail appropriés où elles peuvent être facilement redéfinies, supprimées ou résolues pour améliorer la qualité globale de l'application. Les changements de build à build doivent également être surveillés dans le cadre du processus en cours, afin de garantir que la qualité du logiciel ne se détériore pas.
Le meilleur moment pour résoudre la dette technique dans le code hérité est lorsque vous apportez des modifications. Les données déclarées doivent être incluses dans les informations statistiques globales sur le projet. La dette technique peut ne pas avoir d'impact immédiat sur l'application, mais vous devez appliquer les meilleures pratiques pour la contenir et la gérer systématiquement. La refactorisation du code hérité chaque fois que vous devez apporter des modifications vous aide à réduire progressivement la dette.
Assurer la couverture sur le code modifié
Ce processus permet de garantir que la portée des modifications n'a pas d'impact négatif sur les fonctionnalités existantes, mais vous devez également vous assurer que l'équipe suit les bonnes pratiques pour aller de l'avant. Continuer à maintenir un haut niveau de couverture et à écrire ou mettre à jour des tests au fur et à mesure que le code évolue nécessite l'adhésion au niveau culturel. C'est pourquoi nous avons créé une technologie qui peut vous avertir automatiquement lorsqu'un code modifié (c'est-à-dire un code nouveau ou modifié) n'est pas conforme à la politique de couverture.
En analysant les changements entre les versions de base spécifiées, vous pouvez vous concentrer sur et surveiller les changements dans l'ensemble de la base de code pour vous assurer que rien ne passe entre les mailles du filet. Atteindre une couverture de 100% sur l'ensemble de la base de code n'est pas pratique, mais en surveillant la couverture du code modifié, l'équipe peut se concentrer sur les parties du code qui sont activement travaillées et avoir l'assurance que toutes les modifications sont testées.
Pour conclure, les logiciels du monde fonctionnent avec du code qui a été transmis d'équipe en équipe. La gestion du code hérité est une réalité quotidienne. Les lacunes dans les connaissances sur le code représentent des risques potentiels lorsque les développeurs apportent des modifications pour maintenir ou étendre les fonctionnalités, et les processus et technologies utilisés ici devraient vous aider à gagner en confiance pour assumer à peu près n'importe quelle poussée de base de code sur vos équipes.