Si vous évoluez, de près ou de loin, dans l’univers du développement logiciel, vous avez dû entendre parler de dette technique.

Le terme, que l’on doit à Ward Cunningham, évoque le choix que l’on fait lors d’un développement de mettre en place une solution rapide mais bancale au lieu d’une solution propre mais plus longue. La première solution permet d’atteindre des objectifs à court terme mais impactera directement la qualité du logiciel développé. Les conséquences seront négatives sur le moyen et long termes : il s’agit de la dette, qu’il faudra rembourser, plus les intérêts !

En réalité, au-delà du choix de faire « trop vite », tout développement logiciel inclut fatalement une part de dette, car il est impossible de produire un code totalement dénué de bogue, et toute technologie est condamnée à devenir obsolète un jour, ce qui impliquera un coût de mise à jour.

Pour être explicite, la dette technique peut être contractée lorsque :

– L’on décide de livrer une fonctionnalité de mauvaise qualité rapidement pour respecter un délai,

– Lorsque l’on repousse la mise à jour des frameworks utilisés au risque de se retrouver avec un logiciel basé sur une version obsolète, sachant que toutes les technologies évoluent,

– Lorsque l’on privilégie le code pur en oubliant volontairement ce qui devrait aller avec : la documentation, les tests, etc,

– Lorsque l’on décide de faire évoluer son logiciel sans être trop sûre de la qualité du logiciel ‘de base’.

Autant de cas de figures, qui nous font dire que la dette technique ne peut pas être évitée dès lors que l’on code. Mieux vaut apprendre à vivre avec et surtout la maîtriser. Et éviter de développer plus que ce qui est nécessaire à notre besoin métier.

Mais comment faire ?

Plusieurs méthodes permettent de réduire la dette : prendre conscience qu’elle existe (déjà), l’intégrer au backlog et idéalement y consacrer une personne, mettre en place de la documentation ou encore s’assurer que les développements soient encadrés par des tests.

C’est sur ce dernier point que nous allons nous concentrer.

S’il s’agit d’un premier jalon, essentiel pour se prémunir contre le code truffé d’imperfections, la mise en place des tests reste l’une des premières ‘victimes’ lorsque l’on favorise la livraison rapide à la qualité du code. En effet, il s’agit d’une discipline délicate et qui demande un investissement important : autant de temps que l’équipe technique n’utilisera pas pour développer de nouvelles fonctionnalités.

Pourtant voici plusieurs raisons qui vous amèneront à ne pas passer outre.

Pourquoi les tests peuvent m’aider à maitriser ma dette technique ?

Pour trois raisons principales :

Les tests vous permettent de valider vos développements et vérifier objectivement la fiabilité de votre logiciel.

Sans ces tests, vous n’avez aucune maîtrise sur votre code et n’avez aucune idée réelle de son état de fonctionnement. Les tests permettent de confirmer la solidité de vos développements, de les sécuriser.

Cette étape est nécessaire pour les évolutions futures de votre application. Et ce d’autant plus que les développeurs seront bien moins enclins à coder sur du code dont ils ne connaissent pas la qualité. Le risque de causer d’avantages de problèmes en codant sur du code mort ou fragile est trop grand.

Les précautions supplémentaires, qui seront nécessaires, auront un impact direct sur le temps de développement de vos prochaines évolutions. Ce ralentissement et les coûts que cela implique sont de bons exemples d’intérêts que vous pourriez avoir à rembourser.

Les tests vous permettent d’envisager le refactoring de vos applications.

Lorsqu’une partie d’un logiciel n’est plus maintenable car trop complexe, on peut vouloir retravailler le code source afin de le restructurer sans toucher aux fonctionnalités. Le refactoring permet directement de réduire la dette technique de votre logiciel puisqu’il rend votre code « plus propre ». Il s’agit d’un processus difficile. Pourtant, sans tests, il devient quasiment impossible de refactorer son application puisqu’ils permettent de s’assurer que les changements sont bien faits et que l’application refactorée donne les mêmes résultats que l’application d’origine.

Retour d’expérience

« Les tests permettent de mettre en place des refontes techniques. Sans cela, on touche au code source sans savoir si ça va marcher. On est comme tétanisé. »

– David Rouillon, Architecte

Les tests vous permettent d’identifier les problèmes et de les corriger tôt dans le processus de développement.

Une fois le logiciel développé et les problèmes constatés, il devient difficile sans tests d’identifier clairement ce qui ne convient pas, puis d’améliorer le code et réduire sa dette.

Vous pourriez décider de mettre en place des tests à la fin de vos développements ; mais attention, mettre en place des tests a posteriori demande plus d’investissement, surtout lorsque l’application n’a pas été conçue pour. Daniel Cohen-Zardi, Président de SoftFluent, rappelle dans son article sur les meilleures pratiques du test logiciel qu’une erreur de conception détectée en phase de spécifications coûte 1 à corriger, 10 lorsqu’elle est détectée lors des tests de qualifications, et potentiellement jusqu’à 100 lorsque le logiciel est déjà déployé.

Ce constat étant fait, nous conseillons bien évidemment de penser les tests en amont et de les développer au fur et à mesure des développements, ce sera un gain de temps et cela vous prémunira contre du ‘mauvais code’. L’idéal étant d’automatiser vos tests.

Daniel Cohen-Zardi dit, à ce sujet :

« Notre conviction sur les tests [unitaires, d’intégration et du système], est que pour des logiciels métiers, il convient d’automatiser au maximum ces tests. Du point de vue financier, un test déroulé manuellement est une charge. Un test consolidé dans un script re-jouable à l’infini est un investissement. »

Retour d’expérience

« Plus la fonctionnalité est critique dans la solution développée plus les tests sont primordiaux. Ils permettent de rassurer toutes les personnes impliquées dans la création du logiciel et prouvent qu’il fonctionne bien en simulant concrètement l’utilisation que pourrait en avoir les utilisateurs.

Dans ce cas-là, la mise en place de tests d’intégration automatiques relève du bon sens. Même s’ils sont plus longs à exécuter, ils représentent un réel investissement puisqu’ils seront utilisés durant toute la vie du logiciel. »

– David Rouillon, Architecte

En pratique, qu’est-ce que cela donne ?

Un de nos clients a souhaité basculer son application, développée en C++, sur une autre technologie afin d’améliorer sa maintenabilité et a fait appel à nous afin de la migrer en .NET. Son logiciel, dont le but est de fournir des données sous forme de Web Services, devait conserver les fonctionnalités d’origine.

L’application en C++ disposait déjà de tests unitaires (un test unitaire vise à tester un seul composant hors de son environnement, ex : clic sur un bouton). Nous avons donc décidé de développer un système de tests identiques en .NET, de centraliser les résultats et de les comparer. Puisque nous testions la même fonctionnalité en suivant le même scénario en C++ et en .NET, obtenir un résultat identique nous a permis de valider le développement.

Les tests ont été automatisés puisque les volumes nécessaires pour avoir une couverture suffisante n’étaient pas envisageables à échelle humaine.

Pour réaliser cette migration il est incontournable de passer par des tests. Ils nous permettent ici de :

– partir sur une base solide,

– de pouvoir commencer le développement sûrement et rapidement et

– de s’assurer que la nouvelle application fonctionne au même titre que l’application précédente.

Cela nous a permis également d’aller plus loin en détectant ce qui ne fonctionnait pas à l’origine, dans le logiciel en C++, et corriger ces bugs dans la version développée en .NET.

Petite particularité : les tests développés n’ont de sens que dans le cadre de la migration et ont pour vocation à disparaître puisqu’au final, la solution en C++ elle-même disparaitra.

En pratique, il peut être très compliqué de mettre en place des tests logiciels notamment car il n’est pas évident de maitriser les temps de développement quand on doit faire face aux aléas de la gestion de projet (ex : réévaluation du besoin, etc.). C’est une raison de plus d’insister sur cet aspect jusqu’à ce qu’il s’inscrive dans les habitudes de l’équipe.

Si l’élaboration des tests seront sous la responsabilité de l’équipe technique, leur intérêt doit être appréhendé par toutes les parties prenantes.

Ainsi, le décideur IT en charge du projet à tout intérêt à exiger la mise en place de ces tests et ce dès le début. Et il est de la responsabilité des prestataires externes, tels les ESN, de les intégrer dès le calibrage afin de s’assurer qu’ils seront pris en compte tout le long du projet de développement et que le logiciel développé aura les outils nécessaires pour permettre à l’entreprise commanditaire de maîtriser sa dette technique.

Ne ratez plus aucune actualité avec la newsletter mensuelle de SoftFluent

Newsletter SoftFluent