Qu’est-ce que le Contract Testing?

Topics DevSecOps Contract Testing

Définition

Le contract testing (ou test de contrats) est une forme de test logiciel qui évalue les interactions entre différents services applicatifs. Il s’agit d’un moyen rapide et évolutif de valider que les services, tels que ceux d’une application cloud native, communiquent efficacement les uns avec les autres. De cette manière, les tests de contrats aident les développeurs à identifier les problèmes susceptibles de provoquer des incompatibilités ou des dégradations de performance.

Aperçu

Pour offrir une expérience idéale à l’utilisateur, les développeurs doivent s’assurer que les services logiciels peuvent interagir conformément à des exigences de base spécifiques, telles que répondre à une requête dans un délai donné. Les tests de contrats aident les développeurs à s’assurer que les services répondent à ce type d’objectifs. Grâce au contract testing, les équipes peuvent automatiquement vérifier si les interactions entre les services sont conformes aux conditions prédéfinies.

Qu’est-ce que le contract testing ?

Le contract testing est un type de méthodologie de test de logiciel qui évalue les interactions entre les services logiciels, dans le but de confirmer qu’ils respectent les termes d’un « contrat ».

Dans ce contexte, un contrat fait référence à un ensemble de règles qui définissent comment les services sont censés interagir. Par exemple, un contrat peut spécifier les types de réponses qu’un serveur peut envoyer à un client. Les contrats peuvent également définir des objectifs de performance, tels que l’achèvement d’une réponse en un certain nombre de millisecondes.

L’importance du contract testing

De nombreuses applications modernes sont composées de services distincts qui doivent interagir en permanence les uns avec les autres. En cas de dysfonctionnement dans les interactions, les applications risquent soit de ne pas fonctionner, soit de ne pas répondre aux attentes en matière de performance.

Par exemple, une application cloud native basée sur des microservices peut inclure, entre autres composants, un service chargé d’afficher le frontend et un autre service dédié à la récupération de données depuis une base de données. Afin d’obtenir les données destinées à l’interface utilisateur, le service frontend envoie des demandes au service backend, lequel collecte les données et les retourne ensuite au frontend. Dans le cas où les données provenant du backend seraient reçues dans un format incompatible avec le service frontend, une erreur surviendrait et l’interface utilisateur risquerait de ne pas s’afficher. De même, si la transmission des données du backend vers le frontend est trop lente, cela peut entraîner un temps de chargement élevé de l’application et dégrader l’expérience de l’utilisateur.

Le contract testing permet d’éviter ce genre de problèmes en évaluant automatiquement les interactions entre les services logiciels et en déterminant si elles respectent les termes d’un contrat prédéfini. De cette manière, les développeurs peuvent rapidement confirmer que les composants logiciels sont en phase et capables de communiquer de manière efficace et fiable.

Les tests contractuels sont d’autant plus utiles que les services logiciels peuvent changer fréquemment, en particulier dans les projets qui adoptent un processus de livraison continue dans laquelle les développeurs mettent fréquemment en œuvre des mises à jour et les déploient dans des environnements de production. Grâce au contract testing, une équipe de développement peut facilement et efficacement exécuter des tests avant le déploiement pour confirmer que les modifications apportées à un service n’empêchent pas ce dernier d’interagir correctement avec un autre service.

Comment fonctionne le contract testing ?

Le contract testing suit généralement les étapes suivantes :

  1. Identifier les services à tester : tout d’abord, l’équipe de développement choisit les services à tester en repérant ceux qui interagissent fréquemment entre eux.
  2. Définir un contrat : à l’aide de code, les développeurs établissent les termes du contrat logiciel. Ces termes déterminent exactement les interactions de service à évaluer.
  3. Réaliser le test : une fois le contrat défini, l’équipe exécute le test en envoyant ou recevant des requêtes de service dans un environnement de test, afin d’observer et d’évaluer les réponses des services.

Un certain nombre d’outils sont disponibles pour faciliter le processus de définition du code contractuel et d’exécution des tests. Plus loin, nous vous présenterons une série de solutions populaires dans la section consacrée à la mise en œuvre du contract testing.

Contract testing VS tests d’intégration

Un autre type de test couramment effectué par les développeurs pour évaluer la qualité de l’interaction entre les services est le test d’intégration.

Le contract testing et les tests d’intégration sont similaires en ce sens qu’ils permettent tous deux d’évaluer les communications entre les différents services. Cependant, dans la plupart des cas, les tests d’intégration impliquent l’exécution de tests de bout en bout. Cela signifie que les développeurs doivent tout d’abord déployer une instance d’application complète, qui peut inclure de nombreux services discrets. Ensuite, ils génèrent des demandes pour tester la capacité de l’ensemble des services à les traiter.

À l’inverse, le contract testing se concentre généralement sur les interactions entre seulement deux services spécifiques. Comparé aux tests d’intégration, le contract testing présente des avantages tels que :

  • Simplicité : le contract testing ne requiert pas le déploiement d’une instance d’application complète. Les équipes n’ont qu’à déployer les services spécifiques qu’elles souhaitent évaluer.
  • Vitesse : le contract testing se limitant à tester les échanges entre deux services, il permet souvent d’obtenir des résultats plus rapidement que les tests d’intégration.
  • Une analyse plus claire des causes profondes : en testant seulement deux services, il est plus facile d’identifier la source d’un problème, comme une réponse lente à un certain type de requête. Avec les tests d’intégration de bout en bout, les causes profondes ne sont pas toujours évidentes, car elles peuvent provenir de n’importe quel composant de l’application.
  • Facilité de maintenance : les tests contractuels sont plus simples à maintenir et à mettre à jour grâce à leur périmètre restreint. Les tests d’intégration de bout en bout peuvent nécessiter une maintenance à chaque modification d’une partie de l’application – et comme les applications évoluent souvent, les développeurs doivent régulièrement mettre à jour les tests d’intégration.

Cela ne veut pas dire que les développeurs ne doivent pas utiliser de tests d’intégration, ou que les tests de contrat peuvent remplacer entièrement les tests d’intégration de bout en bout. Ceux-ci restent utiles pour évaluer la manière dont les utilisateurs finaux vont vivre l’expérience d’une application dans son ensemble. Ainsi, les tests d’intégration de bout en bout sont souvent exécutés au cours des dernières étapes du développement logiciel, peu avant le déploiement d’une application en production. En revanche, le contract testing offre un moyen plus simple et plus rapide de tester les interactions entre des parties spécifiques d’une application, ce qui en fait un moyen précieux d’identifier les bugs plus tôt dans le processus de développement.

Contract testing VS tests d’API

Le contract testing est également comparable à bien des égards aux tests d’API. D’ailleurs, certains considèrent que le contract testing est synonyme de tests d’API, ou du moins qu’il en constitue un sous-ensemble. Toutefois, il existe des différences importantes entre les tests de contrat et les autres types de tests d’API.

Les tests API évaluent le comportement et les performances des interfaces de programmation d’applications, généralement en évaluant la manière dont un serveur API répond à une requête d’un client. Étant donné que les API régissent la manière dont les services interagissent, les tests d’API sont essentiels pour s’assurer que les services peuvent communiquer entre eux de manière efficace.

Le contract testing poursuit un objectif similaire en ce sens qu’il permet aussi d’évaluer les interactions des services qui, dans la plupart des cas, communiquent par l’intermédiaire d’API. La différence entre ces méthodologies de test réside toutefois dans le fait que les tests contractuels se concentrent généralement sur la confirmation que les services interagissent d’une manière qui correspond aux objectifs de compatibilité et de performance. Les tests d’API ont un champ plus large, car ils permettent également de vérifier les risques de sécurité des API.

En outre, le contract testing s’appuie parfois sur des interactions API fictives. Cela signifie qu’au lieu de générer une requête auprès d’un client API réel et d’afficher la réponse qui en résulte, les tests de contrat simulent ce à quoi ressemblerait une requête ou une réponse, sur la base des spécifications de conception d’une API. L’API mocking permet d’effectuer des tests de contrat même si les développeurs n’ont pas entièrement mis en œuvre une API. Les tests d’API peuvent également tirer parti du mocking, mais il est plus courant que les tests d’API évaluent les interactions « réelles » de l’API.

Types de tests de contrat

Il existe deux approches principales du contract testing : celle axée sur le consommateur et l’autre axée sur le fournisseur.

Tests axés sur le consommateur

Dans un test de contrat axé sur le consommateur, le consommateur de service (c’est-à-dire le service qui génère des requêtes et les envoie à un autre service) est chargé de définir les termes du contrat et de déterminer si le service qui répond (appelé fournisseur) les respecte.

Les tests axés sur le consommateur sont utiles dans les projets où les consommateurs changent plus souvent que les fournisseurs. Dans ce cas, les développeurs peuvent exécuter des tests de contrats axés sur le consommateur à chaque fois qu’ils mettent à jour un service consommateur pour s’assurer que les changements n’ont pas introduit de problèmes de compatibilité avec le fournisseur. Ils peuvent également mettre à jour le contrat de service en même temps que le service lui-même, en fonction des nouvelles exigences introduites par les changements de service.

Tests axés sur le fournisseur

Dans les tests de contrat axés sur le fournisseur, le service qui reçoit les demandes et y répond (le fournisseur) définit les termes du contrat. Cette approche est particulièrement utile lorsque le code du fournisseur change plus fréquemment que le code du consommateur ; dans ce cas, les tests axés sur le fournisseur offrent un moyen pratique de valider qu’un fournisseur mis à jour peut toujours interagir avec les consommateurs comme il se doit.

Les tests axés sur le fournisseur peuvent également contribuer à assurer la compatibilité ascendante dans les systèmes où un fournisseur doit interagir avec plusieurs versions d’un consommateur. Grâce aux tests axés sur le fournisseur, les développeurs peuvent confirmer que chaque version du consommateur interagit correctement avec la dernière version du fournisseur.

Comment mettre en œuvre le contract testing

Pour mettre en œuvre les tests de contrats, les équipes doivent d’abord choisir un outil de contract testing. Parmi les options open source les plus répandues, on retrouve :

  • Pact : Pact utilise une approche de tests axés sur le consommateur et prend en charge un grand nombre de langages de programmation courants.
  • Contrat Spring Cloud : Spring Cloud Contract se concentre sur les tests axés sur le fournisseur. Cette solution est axée sur Java et permet aux développeurs de définir des tests à l’aide de Groovy ou de YAML.
  • Dredd : Dredd permet d’automatiser le contract testing en évaluant la documentation de l’API et en testant les interactions entre les services pour vérifier qu’elles sont conformes au comportement défini dans la documentation.
  • RestAssured : RestAssured est une bibliothèque Java qui permet de tester les interactions entre des services écrits en Java qui utilisent des API RESTful.
  • OpenAPI : OpenAPI (anciennement Swagger) n’est pas un outil de contract testing en soi. Il s’agit d’un format de spécification qui permet de définir comment les services doivent interagir. OpenAPI peut être utilisé pour générer des contrats, que les développeurs peuvent ensuite tester à l’aide d’un outil comme Pact ou Dredd.

Contract testing et JFrog

En stockant et en gérant les tests de contrats générés par des outils spécialisés, JFrog facilite l’intégration du contract testing dans le cycle de vie du développement logiciel. Pour en savoir plus, demandez une démonstration.

 

En savoir plus sur sécurité

JFrog Xray

Une solution SCA universelle pour identifier les vulnérabilités de manière proactive.

Explorez JFrog Xray

JFrog Advanced Security

Une solution de sécurité unifiée qui protège les artefacts logiciels contre les menaces qui ne peuvent être détectées par des outils de sécurité cloisonnés.

Explorez JFrog Advanced Security

JFrog Curation

Utilisez les logiciels Open Source en toute confiance en contrôlant les composants approuvés et en bloquant les paquets malveillants.

Explorez JFrog Curation

Release Fast Or Die