Comment mener des tests avec agilité et assurance?
Dans un contexte caractérisé par un marché en évolution constante et par un délai de mise sur le marché toujours plus court, comment peut-on garantir la qualité des applications informatiques avec agilité et assurance?
Dans cet entretien, Jean François Poilprêt (JP), Senior Manager, et Benjamin Audren (BA), consultant au sein de l’équipe de test d’ELCA, expliquent comment des tests automatisés et un l’intégration continue permettent une amélioration constante de la qualité des logiciels, même avec des cycles de développement courts.
Dans un contexte caractérisé par des délais de commercialisation toujours plus courts, comment est-il possible d'assurer la qualité des applications informatiques ?
JP - De nos jours, c’est l’un des principaux enjeux en informatique! En effet, nos clients sont désormais plus impliqués dans l’élaboration du produit final, ils souhaitent voir des résultats plus tôt et ils veulent une livraison plus rapide pour que l’utilisateur final puisse en tirer tous les avantages au plus vite. Avec de telles attentes, une multitude de nouvelles méthodes ont fait leur apparition pour gérer le cycle de production d’une application, en particulier toutes les méthodologies dites «agiles» (Extreme Programming, SCRUM). Chez ELCA, nous avons développé notre propre méthodologie, baptisée AgileIT, afin de répondre à la demande de nos clients. Les méthodes agiles impliquent des cycles de développement courts (de deux à six semaines). On parle de «sprints». La raison d’être d’un sprint est de permettre la livraison d’un système utilisable avec toutes les fonctionnalités prévues.
Tout cela semble très complexe à faire en un temps réduit. Comment parvenez-vous à assurer la qualité?
JP - Un délai aussi court pour un cycle de développement complet a réclamé une nouvelle manière de gérer l’équipe du projet et de rendre le processus de test plus efficace. Ainsi, chaque sprint se concentre sur un ensemble de fonctionnalités (ou "scénarios utilisateurs") mais doit aboutir à la livraison d’un système que l’on peut mettre en exploitation immédiatement si nécessaire, et qui reprend bien sûr toutes les fonctionnalités des sprints précédents, sans les détériorer. D’un côté, sans test correct, le risque de régression (à savoir le dysfonctionnement d’une fonctionnalité jusque-là parfaitement normale) est élevé. Mais de l’autre, le fait de tester toutes les fonctionnalités à de multiples reprises (à chaque sprint) peut s’avérer coûteux et être une perte de temps. C’est là que l’automatisation des tests entre en jeu: procéder au test automatique d’une fonctionnalité est certes plus cher que de la tester une seul fois manuellement, mais le retour sur investissement est très rapide si l’on utilise ce processus à plusieurs reprises, car les tests suivants n’entraîneront aucun coût supplémentaire et la livraison des nouvelles versions se fera plus rapidement!
L’automatisation des tests est prometteuse, mais comment garantissez-vous au quotidien la qualité des développements?
JP - Afin de garantir l’efficacité des sprints, les méthodologies agiles insistent également sur la détection d’erreurs et correction dans les plus brefs délais. L’intégration continue rend cela possible: à chaque fois qu’un membre de l’équipe a fini de développer une fonctionnalité, il en ajoute le code source au code général du projet (qui est stocké dans un dépôt central de code source), afin qu’une machine dédiée puisse (1) avoir accès à la dernière version du code source de l’ensemble du projet, (2) compiler le programme à partir de ce code, (3) mettre en place l’application sur un environnement spécifique pour le tester et, enfin, (4) mener tous les tests automatiques sur le programme récemment installé.Après cela, l’équipe du projet reçoit une notification avec les résultats, en particulier si une erreur a eu lieu lors de la phase d’intégration continue: le développeur responsable du problème (c’est-à-dire celui qui a ajouté son code source en dernier, on dit qu’il a "cassé le build") doit réparer au plus vite le dysfonctionnement en question. Avec cette méthode de travail, nous pouvons garantir que la dernière version du code source génère un système opérationnel. Par ailleurs, être capable de réparer une erreur dès qu’elle apparaît est beaucoup plus simple que de le faire plus tard, surtout si elle est découverte alors que l’application est en production.
Est-il possible d’automatiser tous les types de tests pour une application donnée?
BA - On a toujours envie de répondre "oui" à ce genre de questions. En pratique, il convient de faire la différence entre tester et utiliser une application. Dans la plupart des cas, le logiciel ne peut pas être manipulé automatiquement de toutes les manières souhaitées afin de simuler la façon dont un utilisateur s’en servirait. En fonction de sa complexité et des différentes interactions avec d’autres programmes installés sur une machine, l’automatisation peut s’avérer chronophage à élaborer et à maintenir. Toutefois, le test ne consiste pas uniquement à utiliser l’application en question: il s’agit avant tout de percevoir son état actuel et d’identifier tout dysfonctionnement. Dans ce processus, l’étape du contrôle est essentielle et il est possible de l’automatiser très facilement en raison de sa nature explicite (ces nombres doivent être les mêmes, l’utilisateur ne doit pas pouvoir faire ça, etc.). Mais cette vérification ne porte que sur les attentes du cahier des charges et ne garantit pas que le système fonctionne réellement. Les opérations de test devraient également comprendre des investigations, des questions ou encore une exploration du programme. Elles peuvent aussi aboutir à des résultats ouverts. Ces tests dits "d’exploration", sont des tests dits "intelligents" et peuvent être assistés par des outils d’automatisation, tout comme un bon environnement de développement intégré aide les programmeurs en assurant une partie des tâches les plus fastidieuses. En s’affranchissant, grâce à l’automatisation, des étapes les plus répétitives et les plus susceptibles d’entraîner des erreurs, l'équipe Agile peut profiter davantage de la connaissance que les développeurs ont du produit pour trouver et corriger les problèmes, et parvenir ainsi à une meilleure qualité.
Comment décidez-vous ce qui doit être automatisé et ce qui ne doit pas l’être?
JP - C’est toute la question! C’est compliqué: tout le monde préférerait que la totalité des tests soit automatisée, mais comme cela a déjà été dit, c’est impossible. Par ailleurs, nous ne disposons pas de ressources et d’un temps infinis pour tout automatiser comme nous le voudrions. Le plus souvent, nous adoptons une démarche fondée sur l’évaluation du risque et de la valeur, ainsi que sur une estimation simple du retour sur investissement. Tout d’abord, nous hiérarchisons toutes les fonctionnalités selon la valeur ajoutée qu’elles apportent aux utilisateurs, et nous intégrons également la fréquence d’utilisation dans notre appréciation. Cette hiérarchisation est ensuite pondérée selon le risque que représente, pour nos clients, un dysfonctionnement de chaque fonctionnalité (nous pouvons par exemple être en mesure d’estimer les pertes par jour si une fonctionnalité n’est pas utilisable). En fonction de la complexité du domaine d’activité du client et du code source du logiciel, nous prenons parfois en compte la probabilité qu’un élément de l’application cesse de fonctionner à long terme (régression), mais également du nombre de fonctionnalités qui dépendent du même code. Enfin, nous évaluons le degré de difficulté de l’automatisation d’un test (et donc des efforts que cela implique), par comparaison avec une exécution manuelle. Il n’est pas toujours simple d’élaborer des règles claires quant au choix des opérations de test qui doivent être automatisées. En pratique, il nous arrive de seulement définir des principes généraux. Dans le cas d’un projet développé selon la méthodologie agile Scrum, nous pouvons prendre une décision collectivement lors du développement d’une fonctionnalité, ou bien avant, au cours de la réunion de planification du sprint et en accord avec le propriétaire du produit ("Product Owner").
Quel est le degré de pérennité des méthodes de test pour les applications en développement?
BA: Nous avons déjà parlé de la nécessité de définir des scénarios pour les contrôles automatiques, en raison du temps et de l’effort que cela implique. S’il fallait répéter les efforts déployés pour l’automatisation des tests à chaque évolution d’une application, cela serait inquiétant. Il serait en effet impossible de maintenir le rythme dans le cas d’un logiciel évoluant très rapidement. C’est là qu’intervient, heureusement, la conception architecturale du processus d’automatisation. En ayant recours à un motif d’architecture logicielle, il est possible d’isoler les éléments techniques potentiellement instables à partir des descriptions de haut niveau des scénarios de tests. Grâce à cela, les scénarios de tests deviennent facilement maintenables. Ils peuvent aussi servir directement de descriptions claires des différentes fonctionnalités.
A titre d’exemple, un scénario de test peut utiliser des mots-clés tels que "Ajouter un nouvel utilisateur" ou "Publier un document", afin d’identifier une application d’après ce qu’elle est en mesure de faire. L’implémentation proprement dite (qui est l’étape la plus sensible à l’évolution d’une application) se fera sur la base de ces mots-clés. L’avantage qu’il y a au fait de disposer de ce type de scénarios stables, automatisés et faisant office de documentation, est qu’ils résisteront à une refonte de l’application ou à une modification majeure de l’interface graphique. Dans la mesure où ces scénarios contrôlent les fonctionnalités du point de vue de l’utilisateur final, ils empêchent toute régression et l’équipe de développement peut être certaine que les changements apportés à l’infrastructure de l’application n’affecteront pas sa surface. De nos jours, la refonte en profondeur d’une application pour satisfaire aux exigences nouvelles du marché est un défi courant. Il peut s’agir de concevoir à nouveau les structures sous-jacentes pour améliorer les performances du programme, d’introduire des micro-services pour pouvoir découpler et agrandir une équipe, d’externaliser une partie de l’application ou encore de s’appuyer sur des sources de données externes. Disposer d’un processus de test automatisé, solide et durable, permet de garantir le niveau de qualité et de libérer des ressources afin de réaliser tous ces objectifs avec agilité et confiance.