change de nom...
Dans cet article, nous découvrons comment simplifier les tests d'API externes sans recourir aux mocks, grâce à PHP-VCR, un outil qui enregistre les requêtes HTTP et permet de les rejouer.
Lors du développement d'applications faisant appel à des API externes, il est important d'assurer des tests d'intégration fiables et efficaces. Évaluer les interactions avec ces API s'avére souvent complexe et coûteux. Les défis liés aux dépendances réseau, aux limitations de disponibilité et aux variations des réponses rendent cette tâche particulièrement exigeante.
Les tests d'intégration jouent un rôle crucial dans la vérification de l'interaction entre différents composants d'une application. Lorsqu'une API externe est impliquée, des défis spécifiques surgissent, comme les coûts élevés liés aux requêtes fréquentes, les restrictions d'utilisation, ou encore les problèmes de réseau tels que des interruptions de service. Maîtriser ces défis est essentiel pour garantir la stabilité des tests.
Afin de dépasser ces défis, il est souvent avantageux d'adopter des méthodes de test qui allient robustesse et flexibilité, permettant ainsi de mieux anticiper et de gérer les aléas des environnements externes.
Dans cette présentation, nous explorerons différentes approches pour tester les API externes sans recourir aux mocks, en mettant l'accent sur PHP-VCR, une solution permettant d'enregistrer et de rejouer les requêtes HTTP. Grâce à PHP-VCR, les tests deviennent non seulement plus simples, mais aussi plus fiables, ce qui réduit le temps et les efforts nécessaires à leur maintenance.
Imen Ezzine a brillamment présenté les avantages et les limites des différentes méthodes de test. Nous allons explorer comment PHP-VCR simplifie les tests d'intégration tout en augmentant l'indépendance vis-à-vis des API externes.
Lors de la conférence, plusieurs méthodes de test ont été examinées, chacune avec ses points forts et ses faiblesses. Voici un aperçu des principales approches, telles qu'exposées par Imen Ezzine.
Méthode | Avantages | Inconvénients | |
---|---|---|---|
Environnement Sandbox | - Permet d'isoler les tests dans un environnement contrôlé. - Assure une fiabilité des résultats sans risque d'impact sur les systèmes en production. |
| |
Mocking des API | - Simulation des réponses pour des tests rapides et flexibles. - Contrôle total sur les scénarios et résultats testés. | - Peut s'écarter de la réalité si les mocks ne sont pas bien alignés avec l'API réelle. - Doit être mis à jour régulièrement pour suivre les évolutions de l'API. | |
Conteneurs (Docker) | - Reproduction d'environnements proches de la production pour des tests réalistes. - Facilité d'intégration avec d'autres services via des conteneurs isolés. | - Configuration initiale complexe, demande de l'expertise et des ressources locales. - Gestion des dépendances réseau et des ressources système. | |
Tests en local (sur API réelle) | - Test direct sur l'API réelle pour valider l'intégration complète. - Offre une couverture réaliste des cas d'utilisation réels. | - Coûteux à cause des requêtes répétées vers l'API externe. - Problèmes liés aux limitations de requêtes (Rate limit). - Sujette aux limitations réseau, erreurs ou indisponibilité de l'API. - Limité aux endpoints utilisant la méthode GET |
1 . Sandbox : Bien que les environnements de test isolés offrent une bonne fiabilité, il est parfois difficile de reproduire fidèlement la fonctionnalité de l'API réelle.
2. Mock : Les mocks permettent un contrôle total, mais leur utilisation peut s'éloigner de la réalité. De plus, maintenir ces mocks peut devenir lourd, surtout si l'API évolue fréquemment.
3. Conteneurisation Locale : Cette méthode peut offrir un haut degré de réalisme, mais elle nécessite souvent une configuration complexe et une gestion des ressources locales.
L'objectif principal est de trouver un équilibre optimal entre efficacité, fiabilité et simplicité dans les tests d'intégration. Ce que l'on cherche à atteindre, c'est avant tout un code plus facile à maintenir grâce à sa simplification, ainsi qu'une réduction de la configuration afin de limiter les risques d'erreurs. Il s'agit également de diminuer les besoins en maintenance pour concentrer les efforts sur l'amélioration continue de l'application. Enfin, la décorrélation des dépendances est essentielle pour garantir des tests plus robustes, moins sensibles aux échecs provoqués par des facteurs externes.
Pour atteindre ces objectifs, PHP-VCR se présente comme une solution idéale. Il fonctionne comme un magnétoscope, en enregistrant et en rejouant les requêtes HTTP, ce qui simplifie nos processus de test.
Prenons un exemple concret pour illustrer l'utilisation de PHP-VCR dans un projet Symfony:
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use VCR\VCR;
use GuzzleHttp\Client;
/**
* Class ApiTest.
*/
class ApiTest extends WebTestCase
{
public function setUp()
: void
{
// Configure PHP-VCR pour utiliser un chemin de cassette spécifique
VCR::configure()->setCassettePath(__DIR__ . '/cassettes');
// Spécifer le format de stockage // par défaut PHP-VCR utilis YAML storage.
VCR::configure()->setStorage('json');
// On initialise PHP-VCR avant chaque test
VCR::turnOn();
}
public function tearDown()
: void
{
// On désactive PHP-VCR après chaque test
VCR::turnOff();
}
public function testApiCall()
{
// On configure PHP-VCR pour enregistrer les requêtes HTTP
VCR::insertCassette('testApiCall');
// Votre code de test qui effectue une requête HTTP à une API
$httpClient = new Client();
$response = $httpClient->request('GET', 'https://jsonplaceholder.typicode.com/todos/1');
// Assertions sur la réponse de l'API
$this->assertEquals(200, $response->getStatusCode());
// On arrête l'enregistrement de PHP-VCR
VCR::eject();
}
}
Dans cet exemple, PHP-VCR enregistre l’appel d'API lors de la première exécution, puis rejoue cette réponse lors des tests suivants. Cela permet d'améliorer la rapidité et la fiabilité des tests, tout en réduisant la dépendance aux services externes.
Pour explorer plus d'exemples, je vous invite à visiter le dépôt officiel de BÉPO : php-vcr-examples.
1. Enregistrement des appels
La première fois qu'un test est exécuté, PHP-VCR intercepte l'appel à l'API et l'enregistre dans une cassette. Cette cassette contient à la fois la requête et la réponse, ce qui permet de conserver une trace de toutes les interactions.
2. Utilisation de la cassette
Pour les exécutions suivantes, si la cassette existe déjà, PHP-VCR renvoie directement la réponse enregistrée, évitant ainsi l'appel réel à l'API.
3. Modes de fonctionnement
PHP-VCR propose plusieurs modes pour gérer les enregistrements :
- `VCR::MODE_NEW_EPISODES` : Enregistre de nouvelles interactions si aucune cassette n’est disponible. Sinon, il lit la cassette existante.
- `VCR::MODE_ONCE` : Utilise la cassette existante une seule fois, et tous les appels suivants se basent sur la réponse enregistrée.
- `VCR::MODE_NONE` : Aucune lecture ni enregistrement n'est effectué, ce qui signifie que tous les appels s'exécutent normalement, comme si PHP-VCR n'était pas activé.
PHP-VCR est également extrêmement flexible et peut être personnalisé selon vos besoins :
PHP-VCR permet une personnalisation avancée des requêtes en activant les "matchers" souhaités avec la méthode enableRequestMatchers() . Cela permet de contrôler comment les requêtes sont associées et traitées.
\VCR\VCR::configure()->enableRequestMatchers(['method', 'url', 'host']);
Il est également possible de définir des matchers de requêtes sous forme de fonctions de rappel, permettant ainsi de les combiner avec les matchers existants via addRequestMatcher() .
\VCR\VCR::configure()
->addRequestMatcher(
'custom_matcher',
function (\VCR\Request $first, \VCR\Request $second) {
// custom request matching
return true;
}
)
->enableRequestMatchers(['method', 'url', 'custom_matcher']);
Les library hooks permettent à PHP-VCR d'intercepter les requêtes HTTP issues de ces libraries. Lorsque cURL est utilisé pour faire des requêtes HTTP, il est possible de demander à VCR de les surveiller avec une configuration très simple :
\VCR\VCR::configure()->enableLibraryHooks(['curl'])
Dès que c'est activé, VCR capture toutes les requêtes cURL. Il est ensuite possible de les rejouer autant de fois que nécessaire, sans avoir besoin que l’API soit toujours accessible. Fini les tests qui dépendent des services externes en direct !
Voici les principaux hooks les plus utilisés que vous pouvez activer selon les besoins de votre projet :
Les cassettes peuvent être enregistrées dans le répertoire de votre choix grâce à la méthode setCassettePath() . De plus, PHP-VCR stocke les interactions HTTP au format YAML ou JSON. Par défaut, le format YAML est utilisé, mais ce choix peut être modifié selon les préférences en utilisant la fonction setStorage() .
Pour illustrer ces concepts, voici un exemple de configuration complète pour PHP-VCR :
\VCR\VCR::configure()
->addRequestMatcher(
'custom_body_matcher',
new CustomBodyMatcher()
)
->enableRequestMatchers(['method', 'url', 'query_string', 'custom_body_matcher', 'post_fields'])
->enableLibraryHooks(['curl'])
->setCassettePath(dirname(__DIR__, 2).'/tests/Environment/IO/cassettes')
->setStorage('yaml')
->setMode(VCR::MODE_ONCE);
En optant pour PHP-VCR, plusieurs avantages peuvent être observés :
Pour garantir un usage optimal de PHP-VCR et maintenir la qualité de vos tests au fil du temps, il est essentiel d'adopter des bonnes pratiques pour l'optimisation et l'entretien des cassettes.
La conférence d’Imen Ezzine a été enrichissante, offrant une perspective unique sur les défis liés aux tests d'API externes. Avec PHP-VCR, vous disposez d'une solution qui renforce la solidité de vos tests et fluidifie votre processus de développement. Tester des API externes peut souvent sembler complexe. Cependant, grâce à PHP-VCR, cette tâche devient beaucoup plus accessible. En enregistrant et en rejouant les requêtes HTTP, vous améliorez l'efficacité de vos tests : ils deviennent non seulement plus rapides et fiables, mais vous n'avez également plus besoin de dépendre des services externes. |