Ce que les tests de charge d'API mesurent réellement

Capacité : combien de requêtes par seconde avant que la latence ne se dégrade. On y répond en générant du trafic concurrent et en surveillant les temps de réponse et les taux d'erreur.

Exactitude : la réponse contient-elle ce qu'il faut. On y répond en posant des assertions sur les corps de réponse par rapport à une attente.

Un test de charge qui ne vérifie que les codes de statut signalera une exécution impeccable alors que chaque réponse contient une liste vide. Le service était rapide et faux, et rapide et faux est pire que lent et juste, parce que personne ne va enquêter.

Ce qu'une suite fonctionnelle vous apprend sur la charge, et ce qu'elle ne vous apprend pas

Les plans de test d'API générés comprennent des cas aux limites et des cas qui ressemblent à du stress : charges utiles surdimensionnées, valeurs hors plage, combinaisons de paramètres inhabituelles. Ils détectent une vraie catégorie de défaillances, et ce ne sont pas des tests de charge. Ils sollicitent les cas limites un par un au lieu de mesurer le comportement sous une concurrence soutenue.

Le partage honnête est donc le suivant. Utilisez un outil de charge dédié pour la capacité. Utilisez la vérification fonctionnelle pour l'exactitude, y compris pour les cas limites qui n'apparaissent qu'avec des entrées biscornues. Aucun des deux ne remplace l'autre, et faire tourner les deux coûte moins cher que de découvrir l'écart en production.

Trois choses à vérifier avant même de lancer un test de charge

Est-ce correct à une requête par seconde ?

  • Faire un test de charge sur un endpoint cassé mesure la vitesse à laquelle vous pouvez avoir tort.

Le nettoyage est-il effectué ?

  • Une exécution de charge qui crée des enregistrements et les laisse en place modifiera le comportement de l'exécution suivante.

L'environnement est-il représentatif ?

  • Des résultats de charge issus d'un environnement qui contient un dixième des données ne sont pas une prédiction, ce n'est qu'un chiffre.

L'exactitude dans des conditions réalistes

L'écart qu'il vaut la peine de combler ne se situe pas entre tests de charge et tests fonctionnels. Il tient au fait que la plupart des suites fonctionnelles s'exécutent sur un environnement propre et inactif : elles ne voient donc jamais les défaillances qui apparaissent quand les données sont volumineuses ou que l'état est désordonné. Lancer des vérifications fonctionnelles sur un environnement déjà utilisé est un moyen peu coûteux de les trouver.

Terminal

npm install -g @testsprite/testsprite-cli
testsprite setup

La même configuration est disponible dans le tableau de bord TestSprite si vous préférez ne rien installer en local. Le reste de la surface CLI se trouve dans le dépôt CLI.

Les quatre éléments qui déterminent la longévité d'une suite d'API — sessions, valeurs capturées, ordonnancement et nettoyage — sont traités dans la documentation sur les tests d'API.

Lire honnêtement un résultat de charge

Les résultats de charge sont surinterprétés plus que presque n'importe quelle autre sortie de test, en général dans deux directions.

Un chiffre issu d'un environnement qui ne correspond pas à la production est un point de comparaison pour votre prochaine exécution, rien de plus. La moitié de la base, un dixième des données, aucun autre trafic, une taille d'instance différente. Présenter ce chiffre comme une capacité, c'est ainsi que des équipes se retrouvent surprises le jour du lancement par un nombre qu'elles croyaient avoir mesuré.

L'autre direction consiste à prendre un test réussi pour une preuve de bonne santé. Si l'exécution n'a posé d'assertions que sur les codes de statut, vous avez mesuré que le service répond vite sous charge, ce qu'il fait très efficacement quand une requête renvoie un ensemble vide. Activez les assertions sur le corps des réponses pour un échantillon de requêtes, et la même exécution vous apprend quelque chose.

Vérifiez l'exactitude à chaque changement

Les tests de charge ont leur place dans une planification régulière ou avant une mise en production. L'exactitude a la sienne sur chaque pull request, parce que c'est là qu'une régression coûte le moins cher à corriger.

  • La GitHub App est un webhook que vous configurez dans le tableau de bord TestSprite. Elle écoute l'événement de déploiement que votre pipeline produit déjà, si bien que rien ne change dans votre dépôt.

  • GitHub Actions place l'étape à l'intérieur de votre propre workflow, configurée depuis le terminal.

Où TestSprite s'insère autour d'une exécution de charge

TestSprite couvre la couche d'exactitude qui donne du sens à un chiffre de capacité. Il sollicite l'API par rapport au comportement que vous attendez, y compris les cas aux limites et les cas d'autorisation, et rapporte ce qui est réellement revenu, pas seulement à quelle vitesse.

La couverture est générée à partir d'une passe de découverte sur le service en cours d'exécution, complétée par la spécification dont vous disposez, de sorte que les entrées biscornues sont incluses sans que personne ait à les écrire. Auto-Authentication maintient les sessions actives tout au long d'une exécution, Dynamic Variables transporte les valeurs d'un appel à l'autre, Dependency Chains déduit l'ordre d'exécution de ce dont chaque cas a besoin et de ce qu'il produit, et Auto-Cleanup supprime exactement ce que l'exécution a créé.

L'intérêt, c'est un socle sous votre travail de performance : avant de passer une journée à mesurer le débit, vous savez que l'endpoint renvoie ce qu'il faut. La concurrence soutenue reste du ressort de votre générateur de charge, et les deux s'exécutent à des rythmes différents sans se gêner.

TestSprite fait-il des tests de charge ?

Non. Il vérifie l'exactitude, y compris les cas aux limites. La capacité sous concurrence soutenue exige un outil de charge dédié.

Peut-on poser des assertions sur le corps des réponses dans un test de charge ?

La plupart des outils de charge le permettent et peu d'équipes l'activent, parce que cela coûte du débit au générateur. À faire sur un échantillon de requêtes plutôt que sur la totalité.

Par quoi commencer ?

Par l'exactitude. Faire un test de charge sur un endpoint qui renvoie la mauvaise chose produit un chiffre assuré qui ne porte sur rien.

À quelle fréquence faut-il faire des tests de charge ?

Avant les mises en production et après les changements d'architecture. Les tests de charge en continu coûtent cher et vous apprennent rarement quelque chose de nouveau entre ces moments-là.

Et les tests de charge dans la CI ?

Une vérification de charge de la taille d'un smoke test peut convenir. Un test de capacité complet dans la CI se traduit en général soit par un niveau de charge sans signification, soit par un pipeline très lent.

En bref

Rapide et faux reste faux.

Les tests de charge d'API répondent à la question de la capacité. Ils ne disent pas si les réponses étaient correctes, et un test de charge limité aux codes de statut passera alors que l'API ne renvoie rien d'utile. Utilisez un outil dédié pour la capacité, vérifiez l'exactitude séparément, et commencez par l'exactitude.