Fermer

avril 28, 2021

Test d'API – Stratégie et outils


Si vous ne faites pas attention, les tests unitaires de votre API de service Web peuvent prendre en charge tous vos tests. Voici une stratégie de test unitaire qui montre ce que signifie le & ldquo; test unitaire & rdquo; une API de service Web.

Vos tests d'API peuvent rapidement devenir incontrôlables si vous ne faites pas la distinction entre les tests unitaires de votre API et les tests d'intégration / de bout en bout. Si vous ne faites pas attention, les tests d'API commenceront à prendre en charge les tests qui n'appartiennent pas à votre API et créeront une duplication parmi vos tests.

Plutôt que de simplement parler d'une stratégie de test d'API, pour montrer comment gérer efficacement votre API. testing, je vais passer en revue une stratégie typique à l'aide d'un outil de test d'API pour démontrer à quoi ressemble cette stratégie en termes réels. Je suis sûr que nous sommes tous choqués et étonnés que j'utilise Telerik Test Studio pour les API pour ces démos. Je sais que je le suis.

Qu'est-ce que le test d'API?

En fin de compte, une API doit être implémentée avec du code et, comme tout autre ensemble de code, vous devez la tester. & ldquo; Test du code & rdquo; est normalement organisé en une hiérarchie de tests unitaires, de tests d'intégration et de tests de bout en bout. Au début de cette hiérarchie, les tests unitaires confirment à la fois que votre code fait la bonne chose lorsqu'il est alimenté par ses entrées et confirme que votre code transmet les bonnes données à ce qui vient ensuite dans la chaîne de traitement (le test d'intégration est l'endroit où vous confirmez que le & ldquo ; faire passer & rdquo; fonctionne correctement).

Avec les API, cependant, les tests unitaires peuvent être là où les roues tombent. Les API étant une interface vers une chaîne de traitement, il est facile de confondre les tests unitaires d'une API avec les tests d'intégration de cette chaîne de traitement. Une stratégie de test d'API efficace identifie ce que & ldquo; teste unitaire d'une API & rdquo; signifie (et ce qu'il ne fait pas) et où le test d'une API s'inscrit dans la hiérarchie de l'intégration et des tests de bout en bout.

API Unit Tests

Comme tout autre ensemble de tests, les tests API suivent la méthode Arrange- Modèle Act-Assert. Étant donné qu'une API commence sa vie comme un ensemble d'URL (avec la fonction API Web d'Azure, vous pouvez définir votre API sans écrire de code du tout), cela signifie que vous commencez votre test d'API avec vos URL, pas avec votre code. [19659009] Organiser

En règle générale, pour les services RESTful, vos URL partagent toutes une URL de base et toutes vos demandes ne sont que des variantes de cette URL. Par exemple, un service client peut ne disposer que de deux URL pour prendre en charge toutes ses opérations CRUD de base:

  • http: /// clients : récupérer tous les clients ou ajouter un client avec le système fournissant l'ID client
  • http: /// clients / A123 : Récupérer / mettre à jour / supprimer / ajouter un client en spécifiant l'identifiant client (& ldquo; A123 & rdquo; dans ce cas)

Pour mon service client, mon URL de base serait http :///les clients. Dans Test Studio pour les API, cela est pris en charge en créant une variable au niveau du projet (appelée, par convention, base-url & mdash; bien que vous puissiez appeler la variable comme vous le souhaitez). En exploitant cette variable, les deux URL pour mes opérations CRUD de base ressembleraient à ceci (Test Studio for APIs utilise des doubles accolades françaises pour marquer les variables dans un test):

  • {{base-uri}} : Récupérer tous les clients ou ajouter un client avec le système fournissant l'ID client
  • {{base-uri}} / A123 : Récupérer, mettre à jour, supprimer ou ajouter un client en spécifiant l'ID client

Configurer mon projet et créer mon Le premier test avec son URL de base prend environ deux ou trois minutes dans Test Studio pour les API et ressemble à ceci:

 Test d'API: Test Studio pour les API montrant un projet avec un test initial et la variable base-url attribuée une URL

Act

Pour les services, une phase de test Act consiste à émettre une requête HTTP en utilisant l'URL de base, un verbe HTTP (GET, POST, etc.) et, potentiellement, certaines valeurs dans le corps de la requête et / ou en-tête.

En général, mon premier test est une simple requête GET utilisant l'URL de base (pour mon service client ce, cela correspondrait à un & ldquo; obtenir tous les clients & rdquo; demander). Dans Test Studio pour les API, les tests consistent en une ou plusieurs étapes, y compris les requêtes HTTP. Donc, pour implémenter mon premier test dans Test Studio pour les API, j'ajouterais une étape de requête HTTP à mon projet avec son verbe défini sur GET et son URL définie uniquement sur ma variable de base-url. Vous pouvez le voir ici (et, encore une fois, cela prend environ une minute à configurer dans Test Studio pour les API):

 Test d'API: Test Studio pour les API montrant un projet avec une étape de requête HTTP dans le test initial . Le test utilise le verbe GET et la variable base-url

Assert

Dans un test API, la phase Assert consiste à vérifier le code d'état de la réponse HTTP et, potentiellement, les valeurs dans le corps de la réponse ou en-têtes. Test Studio pour les API prend en charge cela via les paramètres de l'onglet de vérification pour une requête HTTP. Pour mon test initial, je veux juste vérifier que le code d'état est égal à 200:

 API testing: Test Studio for APIs montrant l'onglet de vérification d'une étape de requête HTTP qui vérifie le code d'état de la réponse pour une valeur de 200

Il peut sembler inutile à ce stade d'exécuter mon test. Après tout, le service n'est même pas encore créé. Cependant, exécuter les tests avant la création du service est le moyen le plus simple de déterminer que mon test peut détecter l'échec (et un test qui ne peut pas détecter l'échec est inutile).

Dans Test Studio pour les API, je clique simplement sur Exécuter bouton. Sans surprise, mon test échoue avec les points rouges traditionnels à côté de l’étape, du test et du projet qui ont échoué:

 API testing: Test Studio for APIs montrant le résultat de l’appel d’un service qui n’existe pas. Le projet, le test et l’étape sont signalés par des points rouges et le résultat du test est affiché au milieu de l’interface utilisateur: le résultat attendu était «200». Le réel était '404'

Je vais éventuellement transformer ce test en quelque chose de plus utile (c'est pourquoi je lui ai donné le nom de & ldquo; Rejeter les utilisateurs non autorisés & rdquo;) mais, pour le moment, je l'ai défini mon projet de test et a prouvé que je peux faire la différence entre le succès et l'échec. Idéalement, cela devrait prendre au plus quelques minutes.

Test d'authentification

Je suis maintenant prêt à commencer à définir mon API. Cela variera en fonction de l'outil que vous utilisez pour créer votre service: si je travaille avec ASP.NET, je vais créer mes contrôleurs (bien que sans aucun code dans mes méthodes) et commencer à exécuter mon service; si je travaille avec la gestion des API d'Azure, je définirai l'API et ses opérations initiales.

À ce stade, ce que je teste est de savoir si je peux accéder avec succès à mon API. En supposant que je n'ai pas mal saisi mon URL de base, c'est le test où je vérifie que je gère correctement l'authentification. Si j'ai une authentification / autorisation en place, je m'attends à récupérer un code de statut 401.

Je changerai mon Assert pour vérifier un code de statut 401 afin que le rejet apparaisse comme & ldquo; passant le tester & rdquo; (c'est-à-dire que dans Test Studio pour les API, je mets à jour le code d'état de l'onglet de vérification sur 401). Maintenant, lorsque j'exécute mon test, je devrais réussir mon premier test et prouver que mon service verrouille les utilisateurs non autorisés.

Pour mon deuxième test, je veux confirmer que les utilisateurs autorisés peuvent accéder au service. Test Studio pour les API générera des en-têtes d'authentification pour moi en fonction d'un nom d'utilisateur et d'un mot de passe (pour l'authentification de base) ou d'un identifiant et d'un secret client (pour OAuth). Cet exemple de mon deuxième test ajoute simplement un en-tête de type abonnement de base à la requête:

 API testing: Test Studio for APIs affichant les en-têtes d'une requête. Un en-tête avec 'MySubscription' comme nom a été ajouté avec la valeur 'phvis'

Lors de l'étape de vérification de ce test, je vérifierai un code d'état indiquant que j'ai enfin atteint mon un service. Encore une fois, cela variera en fonction de l'outil que vous utilisez pour créer votre service Web: avec un service Web ASP.NET, j'obtiendrai un code retour de 200; avec Azure & rsquo; s API Management, j'obtiendrai un code d'état 500 (erreur de serveur interne).

À ce stade, j'ai des tests qui démontrent que, sans authentification, les clients ne peuvent pas accéder à mon service et, avec authentification, ils peuvent.

J'ajouterai également un test pour les requêtes qui ne sont pas prises en charge par l'API pour prouver que, par exemple, un service en lecture seule n'acceptera pas les requêtes de mise à jour ou mal formaté demandes. Ces tests vérifieront également que je produis la bonne réponse lorsque je renvoie des résultats pour des requêtes valides et non valides (dans Test Studio pour les API, je peux utiliser des chemins JSON et XPath pour vérifier mes réponses).

Au fur et à mesure que je construis mes tests , un outil OpenAPI comme Swagger peut être utile pour générer le format du corps de mes requêtes. OpenAPI générera également un schéma JSON que je pourrai utiliser pour déterminer que ma demande et ma réponse sont au bon format (dans Test Studio pour les API, j'ajouterais une étape codée pour valider mes demandes et réponses par rapport aux schémas JSON).

Interfaces de test

Bien que la prochaine étape évidente soit de tester la fonctionnalité réelle de l'API, à ce stade, je m'éloignerai probablement des tests d'API, au moins pendant un certain temps. Cela peut sembler pervers, mais mon API existe généralement pour l'un des quatre objectifs suivants:

  • Méthodes d'appel sur certains objets
  • Ecrire un élément dans une file d'attente
  • Déclencher un événement
  • Appeler une autre API

En unité tester mon API, je suis uniquement responsable de confirmer que je fais les bonnes choses lors de l'interfaçage avec ces objets / files d'attente / événements / services. Par exemple, là où mon code API appelle des objets, je créerai des objets fictifs (dans le monde Telerik, j'utiliserais JustMock) pour confirmer que:

  • Mon API fait les bons appels dans le bon ordre
  • Paramètres reçus par l'API est correctement transmise à ces objets
  • Les sorties des classes sont converties en réponses correctement formatées
  • Les exceptions soulevées par les objets sont correctement formatées dans les réponses et / ou dans les journaux

Où mon service écrit dans une file d'attente ou déclenche un événement, je vais confirmer que:

  • Le bon événement est déclenché
  • Les données sont écrites dans la bonne file d'attente
  • Les erreurs de déclenchement de l'événement ou d'écriture dans la file d'attente sont correctement signalées dans les réponses ou les journaux [19659042] Les données passées à l'événement ou écrites dans la file d'attente sont rétrocompatibles avec ce que mon API a fait dans le passé

Dans Test Studio pour les API, j'utiliserais des étapes codées pour vérifier ces conditions.

Mais cela & rsquo ; s tous mes tests unitaires d'API sont responsables f ou & mdash; il n'est pas responsable de confirmer que les objets / services Web appelés depuis mon API ou les processus qui répondent aux événements / lus dans les files d'attente font les bonnes choses. Lorsque j'appelle un autre service, quelqu'un devrait faire le test unitaire de l'API sur cet autre service Web en utilisant le même type de stratégie que j'ai décrit ici. Quelqu'un devrait également tester de manière unitaire les objets que mon API appelle ou les processus qui lisent dans ma file d'attente / répondent à mon événement. Ces tests peuvent même être exécutés avec un outil différent (dans le monde Telerik, ce serait Test Studio).

Et, dans les tests unitaires de mon API, je suis également limité dans les résultats que je peux vérifier. Lorsque mon service déclenche un événement ou écrit dans une file d'attente, mon API pourrait avoir un nombre potentiellement infini de processus lisant à partir de ces files d'attente ou répondant à ces événements & mdash; Je ne suis peut-être même pas au courant de la plupart de ces processus. Il m’est impossible de garantir que le service fait le bon travail. chose en vérifiant que chaque processus de suivi fonctionne. Dans ces scénarios, ma norme pour & ldquo; mon API fait ce qu'il faut & rdquo; C'est "tout ce que mon API a fait auparavant."

Test d'intégration

Ne vous méprenez pas: finalement, je dois prouver que mon API fonctionne avec ces autres processus. Mais c'est la responsabilité des tests d'intégration (où je manipule des objets ou j'appelle un service Web) ou des tests de bout en bout (où je déclenche un événement ou j'écris dans une file d'attente).

Je vais revenez à mes tests API pour l'intégration mais, comme je regarde plus loin dans la chaîne de traitement, je vais avoir besoin de tests plus compliqués. Cela inclut les tests qui, par exemple, attendent la fin de l'ensemble du processus, puis vérifient les résultats. Dans Test Studio pour les API, je crée plus de tests en plusieurs étapes qui, par exemple, incluent une étape Attendre pour suspendre mon test pendant un certain temps avant de vérifier si mon résultat attendu s'est frayé un chemin à travers le système. [19659003] J'ai donc vraiment trois séries de tests d'API: Mes premiers tests unitaires, mes tests d'intégration et mes tests de bout en bout. Par conséquent, je souhaite que mon package de test me permette d'organiser ces tests dans des groupes séparés (dans Test Studio pour les API, je peux utiliser des dossiers pour organiser mes tests dans mes projets ou créer des projets séparés pour les différents types de tests). [19659003] Vous pouvez garder vos tests d'API sous contrôle en reconnaissant le moment où vous effectuez un test unitaire de votre API et lorsque vous utilisez votre API pour l'intégration ou les tests de bout en bout. Et, lorsque vous testez de manière unitaire votre API, vous ne faites que tester votre API et non les processus qui la sous-tendent.




Source link