Mettre en place des tests d'intégration continus pour un front moderne et un back-end hérité

Mettre en place des tests d'intégration continus pour un front moderne et un back-end hérité
16 min. de lecture

Faire évoluer une interface web moderne sans casser les usages d’un back-end hérité demande plus qu’une suite de tests exécutée avant la livraison. Les tests d’intégration continus permettent de vérifier régulièrement que les composants et leurs interfaces fonctionnent ensemble, tout en donnant à l’équipe un retour exploitable avant la fusion du code.

La difficulté est de trouver le bon équilibre : obtenir un signal rapide pour les développeurs sans masquer les comportements réels du système historique. Voici une démarche progressive qui associe tests ciblés, contrats d’API et quelques parcours de bout en bout, sans imposer une réécriture du back-end.

Tests d’intégration continus : quelle stratégie adopter ?

Pour mettre en place des tests d’intégration continus, automatisez à chaque commit le build et les vérifications adaptées, protégez les échanges front/back par des tests d’intégration et de contrat, puis réservez les tests de bout en bout aux parcours métier critiques. Faites échouer le pipeline lorsqu’une vérification obligatoire échoue et rendez le résultat visible à l’équipe.

L’intégration continue consiste à intégrer fréquemment les changements dans un dépôt partagé et à lancer automatiquement des builds, des tests et d’autres contrôles. GitHub et Microsoft insistent sur le même objectif : obtenir rapidement un retour sur les erreurs et les régressions, au lieu de les découvrir au moment de la livraison.

Un test d’intégration vérifie la collaboration entre plusieurs composants ou services. Il se distingue d’un test unitaire, généralement centré sur une unité de code, et d’un parcours de bout en bout qui traverse une chaîne plus large, parfois jusqu’à l’interface utilisateur.

Dans une architecture front moderne et back-end hérité, aucun de ces niveaux ne suffit à lui seul. Un test unitaire du composant d’affichage ne prouve pas que l’API renvoie les champs attendus ; un parcours complet peut, quant à lui, échouer pour plusieurs raisons et rendre le diagnostic moins direct.

  • Tests unitaires :

    vérifier rapidement les règles et transformations isolables, côté front comme côté back.

  • Tests de contrat :

    vérifier les attentes du consommateur et leur respect par le fournisseur, notamment autour des réponses et des erreurs d’API.

  • Tests d’intégration :

    vérifier des collaborations concrètes, par exemple entre un service back-end et sa couche de persistance.

  • Tests de bout en bout :

    vérifier quelques parcours utilisateurs représentatifs dans un environnement assemblé.

Pour les systèmes pilotés par API, Microsoft recommande de porter une attention particulière aux tests d’intégration et de contrat. Le choix n’est pas de remplacer toute la chaîne par un outil unique, mais d’affecter chaque risque au niveau où il sera le plus facile à observer et à diagnostiquer.

Cartographier les risques entre le front et le back-end hérité

Avant d’écrire le pipeline, identifiez ce que le front consomme réellement. Une documentation d’API est utile si elle existe, mais les usages du code, les échanges observés dans un environnement maîtrisé et les connaissances de l’équipe permettent aussi de repérer les dépendances effectives.

Pour chaque parcours important, notez l’action utilisateur, les appels effectués, les données nécessaires et le résultat attendu. Distinguez les dépendances que vous contrôlez de celles qui appartiennent à un autre service ou à une application historique plus difficile à modifier.

Partir des parcours, puis descendre vers les interfaces

Prenons un exemple de travail fictif : une page affiche les commandes d’un client après un appel à une API historique. L’objectif n’est pas seulement de tester que la page s’ouvre, mais aussi de comprendre ce qui se passe lorsque la liste est vide, qu’une session a expiré ou qu’une réponse ne contient pas un champ facultatif.

  1. Repérez les écrans et actions qui soutiennent les usages métier prioritaires : consultation, création, modification ou validation, selon votre produit.

  2. Pour chacun, listez les requêtes, les paramètres, les formats de réponse et les erreurs que l’interface doit gérer.

  3. Signalez les règles particulières du système hérité : données historiques, transformations, dépendances externes ou comportements documentés par les équipes.

  4. Choisissez les premiers scénarios selon leur importance métier et la possibilité d’obtenir des données de test fiables.

  5. Attribuez un propriétaire au suivi de chaque interface afin de savoir qui analyse une incompatibilité et qui peut modifier le fournisseur.

Cette cartographie est aussi un outil de dialogue. Le développeur front décrit ce dont l’interface a besoin ; le responsable du back-end précise ce que le service garantit réellement ; le produit aide à départager les parcours essentiels des cas moins urgents.

Ne considérez pas automatiquement chaque comportement observé comme une règle métier. Un champ absent, une erreur inattendue ou une valeur incohérente peut révéler un défaut plutôt qu’une promesse à préserver. Décidez explicitement avec les personnes concernées ce qui doit rester compatible et ce qui peut évoluer.

Définir un premier périmètre vérifiable

Commencez par une tranche verticale limitée : un écran, son appel principal et une règle métier importante. Vous pourrez ainsi valider l’accès au dépôt, la création des données, l’exécution des tests et la lecture des résultats avant d’étendre le dispositif.

Documentez également les zones encore non couvertes. Une liste courte et visible des risques restants aide à éviter qu’un premier pipeline vert soit interprété comme la preuve que tout le système historique est sécurisé.

Construire des tests de contrat pour l’API front/back

Le test de contrat répond à une question précise : le fournisseur peut-il satisfaire les interactions dont son consommateur a besoin ? Dans l’approche de Pact, le front joue le rôle de consommateur et décrit ses attentes ; le back-end, fournisseur, vérifie ensuite qu’il peut y répondre.

Cette séparation est particulièrement utile lorsque les deux applications utilisent des technologies différentes ou évoluent à des rythmes distincts. Le front peut tester son client API avec un faux fournisseur, tandis que le back-end vérifie le contrat de son côté. Le contrat partagé formalise les interactions attendues, mais ne remplace pas l’observation de l’ensemble du système en fonctionnement.

Décrire une interaction utile plutôt qu’une réponse exhaustive

Reprenons l’exemple fictif des commandes. Le front demande la liste associée au client connecté et affiche, pour chaque commande, un identifiant, un statut et une date. Le test consommateur doit exprimer les éléments nécessaires à ce comportement, ainsi que les conditions de la requête qui comptent réellement pour l’interface.

  • Requête :

    méthode, chemin et paramètres utiles à l’interaction testée.

  • Contexte :

    état attendu du fournisseur, par exemple un client pour lequel une commande de test existe.

  • Réponse :

    code attendu et structure des données effectivement utilisées par le front.

  • Variantes :

    liste vide ou erreur que le front est censé traiter, lorsque ces comportements font partie de l’accord.

Évitez de figer des détails que le consommateur n’utilise pas. Exiger une valeur littérale ou un champ supplémentaire sans nécessité rend le contrat plus contraignant sans mieux protéger le parcours. À l’inverse, omettre une propriété indispensable à l’affichage laisse une incompatibilité possible hors du contrôle.

Vérifier le contrat côté fournisseur

Une fois les interactions produites par les tests du consommateur, le fournisseur doit les vérifier contre une version identifiable de son application. Pact décrit des contrats au format JSON qui peuvent servir de support à cette vérification entre systèmes hétérogènes.

La préparation des états fournisseur mérite une attention particulière. Pour le cas de la commande, le test doit pouvoir placer le back-end dans un état connu, puis nettoyer ou isoler les données utilisées. Si la création de cet état passe par une dépendance externe inaccessible en CI, une solution contrôlée doit être convenue pour cette dépendance.

Le résultat doit être consultable par les deux équipes : contrat concerné, version vérifiée, interaction en échec et différence constatée. Un échec devient alors une conversation concrète sur l’interface, plutôt qu’un simple message indiquant que « le front ne marche plus ».

Les contrats peuvent remplacer une partie des tests d’intégration système, mais pas tous. Ils vérifient les interactions déclarées ; ils ne prouvent pas à eux seuls que l’authentification, le réseau, la configuration de déploiement et tous les composants assemblés fonctionnent ensemble.

Rendre le back-end hérité testable sans le réécrire

Un système historique peut être difficile à démarrer localement, dépendre de données anciennes ou mélanger logique métier et accès à des services externes. La réponse n’est pas forcément une refonte préalable : protégez d’abord les fonctions critiques et introduisez des points d’accès qui rendent les tests possibles.

Martin Fowler décrit l’idée d’un « test bus » : prévoir des structures permettant aux tests d’accéder aux modules et sous-systèmes sans devoir systématiquement passer par l’interface utilisateur. Dans un back-end hérité, cela peut guider la création progressive de points d’entrée testables autour d’une logique existante.

Créer une frontière autour du comportement important

Supposons qu’une règle détermine si une commande peut être modifiée. Si cette décision est actuellement enfouie dans un traitement plus large, cherchez d’abord un moyen de l’exécuter avec des données maîtrisées et d’en observer le résultat. Selon l’architecture, une interface interne, un adaptateur ou un point d’entrée dédié au test peut constituer une étape utile.

La frontière choisie doit servir le code de production et rester compréhensible par l’équipe. Elle ne doit pas donner aux tests un accès incontrôlé à des opérations sensibles dans les environnements réels. Clarifiez où ce mécanisme est disponible, comment il est protégé et qui peut le maintenir.

  • Identifiez une règle ou une intégration dont la régression aurait un effet métier concret.

  • Conservez les dépendances nécessaires au scénario lorsque leur comportement fait précisément l’objet du test.

  • Remplacez ou isolez les dépendances hors périmètre lorsqu’elles empêchent de préparer un état reproductible.

  • Ajoutez des tests avant de modifier la zone, puis utilisez-les comme filet de sécurité pendant le refactoring.

Cette approche admet un compromis : un test qui conserve davantage de composants réels apporte une observation plus large, mais peut être plus difficile à préparer et à diagnostiquer. Un test plus isolé donne un retour ciblé, au prix d’une visibilité moindre sur l’assemblage complet. Les deux peuvent coexister si leur rôle est explicite.

Pour les changements risqués, consignez les comportements attendus avec les personnes qui connaissent le domaine. Un test de caractérisation peut aider à rendre visible le comportement actuel ; il faut ensuite décider si celui-ci doit être conservé ou corrigé, plutôt que de transformer automatiquement toute sortie historique en exigence permanente.

Microsoft recommande une progression adaptée au code hérité : protéger les zones critiques avec des tests ciblés et accepter, lorsque nécessaire, certaines dépendances existantes. Le but immédiat est de rendre le changement plus sûr, pas de rendre toute l’architecture idéale avant le premier commit testé.

Organiser le pipeline CI du commit à l’artefact

Un pipeline utile donne un retour clair et bloque la progression lorsqu’une vérification obligatoire échoue. Son organisation doit refléter les dépendances entre étapes et la valeur du diagnostic : les contrôles rapides peuvent être lancés tôt, tandis que les vérifications nécessitant un environnement assemblé demandent une préparation plus importante.

  1. Préparer le code :

    récupérer la version à vérifier et installer les dépendances avec une configuration reproductible.

  2. Contrôler et compiler :

    exécuter le build et les contrôles statiques retenus par l’équipe, comme le lint ou certaines vérifications de sécurité.

  3. Exécuter les tests rapides :

    lancer les tests unitaires et les tests du consommateur qui produisent ou valident les attentes du front.

  4. Vérifier les collaborations :

    exécuter les tests d’intégration ciblés et la vérification des contrats côté fournisseur lorsque celui-ci est disponible dans le processus.

  5. Tester l’assemblage :

    lancer les parcours critiques de bout en bout dans un environnement prévu pour les tests.

  6. Conserver le résultat :

    publier les rapports utiles et produire, après les validations requises, un artefact identifiable et prêt pour l’étape de déploiement.

Cette séquence est un modèle à adapter, pas une obligation de tout exécuter en série. Des tâches indépendantes peuvent être parallélisées si l’environnement le permet. La règle importante est de conserver un verdict lisible et de ne pas publier comme validé un artefact associé à un échec bloquant.

Gérer les dépôts et les changements indépendants

Si le front et le back-end partagent un dépôt, la version testée de chaque composant est généralement identifiable dans le même changement. Avec des dépôts séparés, définissez explicitement quelles versions de contrats et de fournisseurs sont vérifiées, où les résultats sont conservés et comment une équipe apprend qu’une modification affecte l’autre.

Un pipeline front vert signifie alors que les contrôles du front ont réussi pour la version et les hypothèses testées. Il ne doit pas être interprété comme la preuve que toutes les versions déployées du back-end sont compatibles. La vérification fournisseur et la traçabilité des versions complètent ce signal.

Prévoyez également une politique de fusion : quels contrôles sont obligatoires, qui peut traiter un échec d’infrastructure et comment relancer une vérification après correction ? Sans cette décision d’équipe, un pipeline existe techniquement mais ne constitue pas nécessairement une protection effective.

Enfin, gardez les secrets hors du code et fournissez aux tests uniquement les accès nécessaires à leur environnement. Les rapports doivent aider à diagnostiquer un échec sans exposer de données sensibles dans les journaux ou les artefacts.

Préparer des données et des environnements de test fiables

La qualité d’un test d’intégration dépend de sa capacité à retrouver un contexte connu. Dans le legacy, cette condition est parfois plus difficile à obtenir que l’écriture de l’assertion elle-même : les données peuvent être partagées, les traitements avoir des effets de bord et les services externes ne pas être disponibles à la demande.

Maîtriser l’état avant et après le test

Pour chaque scénario, décrivez les données initiales minimales, l’action exécutée et les observations attendues. Le test de consultation des commandes, par exemple, doit savoir si le client possède une commande, aucune commande ou une session expirée ; il ne devrait pas dépendre silencieusement de données laissées par une autre exécution.

  • Créer :

    préparer les enregistrements et les configurations nécessaires au scénario par un mécanisme documenté.

  • Isoler :

    éviter qu’une exécution modifie l’état attendu par une autre, notamment lorsque les tests tournent en parallèle.

  • Nettoyer :

    supprimer ou réinitialiser les données produites lorsque l’environnement est réutilisé.

  • Observer :

    conserver assez d’informations pour relier une erreur au scénario et à la version testée.

Lorsque c’est possible, privilégiez des données synthétiques adaptées aux cas métier plutôt que des données réelles inutiles. Si des données sensibles sont indispensables à une investigation, leur usage doit suivre les règles de sécurité et de protection des données de l’organisation.

Choisir les dépendances réelles et simulées

Une dépendance simulée est utile pour déclencher de façon contrôlée une réponse ou une erreur que le front doit gérer. Elle permet aussi de poursuivre certains tests lorsque le service réel n’est pas accessible. En contrepartie, sa fidélité dépend des hypothèses de l’équipe : une simulation incorrecte peut produire un test vert alors que l’intégration réelle est incompatible.

Une dépendance réelle permet de vérifier une collaboration plus large, mais impose de maîtriser sa disponibilité, sa configuration et ses données. Choisissez-la quand cette collaboration constitue justement le risque à couvrir, et non par principe pour tous les tests.

Documentez les différences entre l’environnement de CI et l’environnement cible : authentification, configuration, services appelés et jeux de données. Cette comparaison indique ce que le pipeline vérifie effectivement et ce qui doit encore être observé ailleurs, sans promettre une équivalence parfaite entre environnements.

Sélectionner les parcours de bout en bout et traiter les échecs

Les tests de bout en bout sont précieux pour vérifier qu’un utilisateur peut accomplir une action à travers plusieurs couches. Ils deviennent plus utiles lorsqu’ils portent sur des résultats métier reconnaissables, plutôt que sur une longue série de détails visuels sans lien avec une décision produit.

Pour notre exemple fictif, un parcours pourrait vérifier qu’un utilisateur autorisé accède à ses commandes et voit le statut attendu. Les cas de format détaillés et les variantes d’erreur peuvent être couverts plus près de l’API, tandis que ce parcours confirme l’assemblage essentiel.

Choisir peu de scénarios, mais les choisir ensemble

Avec le produit et les équipes techniques, retenez les parcours dont l’échec empêcherait un usage important : accès à une information, soumission d’une demande ou validation d’une opération, selon le contexte. Pour chacun, indiquez le résultat visible, les préconditions et le responsable de l’analyse en cas d’échec.

Évitez d’utiliser systématiquement l’interface pour préparer tous les états intermédiaires. Si un scénario a besoin d’une commande existante, une préparation contrôlée des données peut rendre l’intention plus lisible que la répétition de toutes les étapes de création à travers l’écran.

Transformer un pipeline rouge en diagnostic

  1. Identifiez l’étape en échec et la version exacte du code ou de l’artefact testé.

  2. Consultez le scénario, les journaux pertinents et, pour un contrat, l’interaction ainsi que la différence observée.

  3. Vérifiez les préconditions : données préparées, disponibilité des dépendances et configuration de l’environnement.

  4. Déterminez si le problème vient d’une régression, d’un test devenu incorrect ou de l’environnement, puis confiez la correction à la bonne équipe.

  5. Relancez les contrôles concernés après correction et conservez une trace de la décision si elle modifie le contrat ou le comportement attendu.

Une relance peut aider à enquêter, mais elle ne devrait pas devenir une manière automatique d’ignorer un test instable. Si un scénario échoue de façon intermittente, isolez sa cause et décidez explicitement de son traitement ; retirer une vérification obligatoire sans suivi réduit la protection que le pipeline est censé fournir.

Un bon résultat de test facilite l’action : nom compréhensible, contexte suffisant et responsable identifiable. Le retour rapide mis en avant par Microsoft n’est utile que si l’équipe peut comprendre et traiter ce retour avant que le changement ne se propage.

Faire évoluer les contrats et piloter l’adoption dans la durée

La mise en place technique ne suffit pas : l’équipe doit aussi convenir de la manière de changer une interface. Une suppression de champ ou une modification de format peut être acceptable pour le fournisseur tout en cassant une version du front encore utilisée. Le contrat aide à rendre cette dépendance visible avant la modification.

Préparer les changements de l’API

Lorsqu’un nouveau besoin apparaît, commencez par décrire l’usage côté consommateur et discuter de la forme de l’interaction avec le fournisseur. Vérifiez ensuite le nouveau contrat côté back-end et gardez une trace des versions concernées. Pour un changement incompatible, prévoyez une transition explicite entre l’ancien et le nouveau comportement plutôt qu’une suppression implicite.

Les contrats peuvent aussi aider à identifier qu’un consommateur ne demande plus un ancien champ. Avant de le retirer, vérifiez toutefois les autres consommateurs connus et les engagements applicables : l’absence d’usage dans un contrat particulier ne démontre pas que personne d’autre ne dépend de ce champ.

Si le fournisseur ne peut pas être modifié immédiatement, plusieurs décisions restent possibles : adapter temporairement le front, introduire une couche de transformation maîtrisée ou maintenir une compatibilité sur l’API. Le choix dépend de la responsabilité de chaque équipe, du risque de divergence et du coût de maintenance accepté.

Suivre des signaux qui aident à décider

Pour un responsable de projet web ou un lead technique, le suivi doit porter sur la capacité de l’équipe à livrer avec un retour exploitable, pas seulement sur le nombre de tests. Quelques questions suffisent pour orienter les améliorations :

  • Les contrôles obligatoires se déclenchent-ils sur les changements concernés et leurs résultats sont-ils visibles avant la fusion ?

  • Les parcours métier prioritaires et les interfaces consommées sont-ils identifiés avec un responsable ?

  • Les échecs sont-ils diagnostiqués et corrigés, ou certaines vérifications restent-elles durablement instables ?

  • Peut-on relier un contrat, une vérification fournisseur et un artefact aux versions qui les ont produits ?

  • Les données, accès et environnements nécessaires aux tests sont-ils documentés et maintenus ?

Réexaminez ces points lors des changements d’architecture ou des difficultés de livraison. Si un contrôle ralentit le travail sans fournir de diagnostic utile, cherchez à améliorer sa préparation ou à déplacer une partie du risque vers un niveau de test plus ciblé, plutôt que de conserver le dispositif par habitude.

Pour approfondir les principes et les outils mentionnés, consultez les ressources de GitHub Actions, la documentation de Microsoft Learn, la documentation de Pact et les travaux de Martin Fowler. Adaptez ensuite les exemples et les mécanismes aux versions et aux contraintes de votre environnement.

Une stratégie robuste commence par une interface et un parcours métier bien compris. Elle combine des contrôles rapides, des contrats vérifiés par les deux parties et des tests d’intégration ou de bout en bout là où l’assemblage réel doit être observé.

Pour avancer, choisissez une première tranche front/back, rendez ses données reproductibles et définissez les contrôles qui bloqueront la fusion. Étendez ensuite la couverture à partir des risques identifiés et des retours de l’équipe, plutôt que d’attendre une modernisation complète du système hérité.

Articles similaires

Protection de vos données

Nous utilisons des cookies pour améliorer votre expérience de navigation, personnaliser le contenu et analyser notre trafic. Vous pouvez choisir d'accepter uniquement les cookies nécessaires ou personnaliser vos préférences.

Tests d’intégration continus : front et back hérité