Les Crash-Devs d'un Passionné

Mocker une API externe

/Catégorie/python

Temps de lecture : 3 minutes

J'étais en recherche d'un outil pour mettre en place un serveur de mock pour mes tests d'intégration.

En effet mocker à la main n'est pas ce qui est des plus simple, puisqu'une API externe évolue à son propre rythme. L'éditeur peut choisir de changer les paramètres d'entrée, le format de sortie ou encore l'adresse des endpoints.

Je ne voulais pas une grosse usine à gaz où je devrais passer 1 semaine à tout configurer ou plus pour maintenir la solution.

Et c'est là que je suis tombé sur VCR

Il s'agit d'une librairie Ruby avec un portage sur python https://vcrpy.readthedocs.io/en/latest/

Omier appel sur les tests d'intégration cette librairie va créer un fichier yaml décrivant cette requête HTTP vers l'API externe. Dès que ce fichier est présent, et que l'on exécute ces mêmes tests d'intégration il va aller cette foisO mocker l'appel HTTP en prenant la configuration dans ce fichier yaml

On commence par configurer la librairie pour notre usage

clipboard
Copier le code
1
2
3
4
5
6
vcr = vcr.VCR( 
   cassette_library_dir="fixtures/cassettes", 
   filter_headers=["Authorization"], 
   filter_query_parameters=["api_key"], 
   decode_compressed_response=True
)

La classe

VCR
est l'objet de configuration :

  • cassette_library_dir="fixtures/cassettes"
    : indique où stocker ces fichiers yaml, ils seront commit sur le serveur afin de ne jamais faire un "vrai appel" API (si
    mode_record="once"
    )
  • filter_headers=["Authorization"]
    et
    filter_query_parameters=["api_key"]
    permettent de ne pas injecter des secrets dans le fichier yaml
  • decode_compressed_response=True
    : permet d'affiche le contenu en clair au lieu d'un binaire Brotli

Et maintenant nous allons créer la fixture

clipboard
Copier le code
1
2
3
4
5
6
@pytest.fixture() 
def cassette(request): 
   module_name = request.module.name.split(".")[-1] cassette_name = f"{module_name}/{request.node.name}.yaml"

   with vcr.use_cassette(cassette_name):
      yield

Cette fixture permet de mettre en place un context manager, c'est-à-dire de lancer les tests (avec l'injection de la fixture cassette) qui applique le mock API

Il suffit d'apposer la fixture cassette sur notre fonction de test pour que la magie opère

def test_call_api(cassette): ...

Maintenant que tout fonctionne, on peut se demander comment maintenir le contrat d'API à jour et donc vérifier que le yaml est toujours frais

Il suffit de supprimer le fichier yaml que vous voulez mettre à jour.

Si vous voulez tous les mettre à jour, il suffit d'appliquer l'option

record_mode="all"
et de rejouer l'intégralité de vos tests d'intégration

clipboard
Copier le code
1
2
3
4
5
6
7
vcr = vcr.VCR( 
   cassette_library_dir="fixtures/cassettes", 
   filter_headers=["Authorization"], 
   filter_query_parameters=["api_key"], 
   decode_compressed_response=True, 
   record_mode="all" 
)

Ainsi tous les fichiers yaml seront recréés en faisant des requêtes HTTP à l'API externe

Voilà une librairie très simple à mettre en place et qui mérite d'être plus utilisée, vous n'avez même pas besoin de définir les url à mocker il fait de l'auto-découverte.