Les tests de performance de zéro à héro

13 minute read

Cet article a pour objectif d’aider les personnes qui mettent en place pour la première fois des tests de performance. Vous y trouverez des conseils sur les bonnes pratiques, les pièges à éviter, et quelques outils.

Image lego carte

Méthodologie

On croit souvent que la difficulté dans les tests de performance est de choisir le bon framework pour faire les tests et d’écrire les tests. Mais de mon point de vue, ce qui est difficile lors de l’écriture des tests est qu’il manque souvent beaucoup d’information. Ce que je conseille vivement c’est de rédiger un document de spécification des tests de performance dont je vais détailler la structure au fur et à mesure de cet article. Dans l’idéal ce document doit être partagé et validé avec l’ensemble des acteurs du projet avant l’écriture des tests. De cette façon tous les acteurs du projet partagent le périmètre réel des tests de performance, ainsi que les hypothèses et les risques associés.

Il est souvent demandé d’estimer la durée d’une tâche. Pour les tests de performance c’est particulièrement difficile. En général je commence par expliquer que pour les tests de performance “On sait quand on commence mais jamais quand on finit” : tout simplement parce que le but de ces tests est de trouver des problèmes, et le temps de correction dépend du problème que l’on n’a pas encore trouvé.

En phase de démarrage des tests de performance, il faut essayer de s’en tenir au strict minimum :

  • peu de scénarios
  • sur un nombre de services réduits
  • en commençant par une charge faible, puis augmenter par paliers pour arriver à la charge cible
  • avec des conditions de succès simple (ex : aucun timeout)

D’expérience le temps s’écoule bien trop vite sur des tests de performance et il vaut mieux les faire étape par étape et étoffer la couverture des tests au fur et à mesure de l’avancée.

Pour donner un ordre d’idée, pour un test de performance pas trop compliqué où tout se passe bien (1 à 2 scénarios) il faut prévoir au moins 2 semaines calendaires.

Passons maintenant au document de spécification des tests de performance dont voici la structure :

1 Cadre général des tests de performance
1.1 Objectif
1.2 Conditions de validation
1.3 Plateforme
1.4 Hypothèses et volumétrie

2. Scénarios utilisés
2.1 Scénario [Nom du scénario]
2.1.1 Description fonctionnelle du scénario
2.1.2 Données d’entrée
2.1.3 Vérifications en fin de tir

3. Tirs et résultats
3.1 Tir du JJ/MM/AAAA
3.1.1 Contexte du tir
3.1.2 Résultats et relevés
3.1.3 Conclusion

Chaque chapitre est ensuite détaillé ci-après.

1 Cadre général des tests de performance

1.1 Objectif

La première étape est de se poser la question sur le besoin fondamental des tests de performance à réaliser, la plupart du temps il s’agit de valider un des aspects suivants :

  • L’application est-elle en mesure de rendre le service attendu pour la future mise en production ? Dans ce cas on cherche à valider que tout fonctionne correctement avec la volumétrie cible.
  • En cas de croissance forte du volume, quels éléments vont être les maillons faibles ou le goulot d’étranglement ? Quelle partie faudra-t-il retravailler pour passer à une échelle supérieure et quel serait le coût d’une augmentation du volume ?
  • Quelle est la limite de l’application ? Quelle volumétrie maximale peut absorber l’application avant de ne plus fonctionner du tout ?
  • On cherche à reproduire la production sur un environnement séparé afin de pouvoir reproduire un bug qui n’arrive qu’en cas de forte sollicitation de l’application.

1.2 Conditions de validation

L’idée ici est de se mettre d’accord en amont et avec tous les acteurs du projet sur un résultat considéré comme validant les performance. En règle générale il faut satisfaire le niveau de service attendu dans le contrat de l’application. Encore une fois il faut se restreindre au nécessaire, ce n’est déjà pas forcément évident d’arriver au résultat positif.

Voici quelques exemples :

  • Toutes les requêtes HTTP répondent 20X : c’est la condition de validation la plus facile à vérifier. S’il n’y a pas de point d’attention particulier je conseille de s’en tenir à cette validation.
  • La page XXX s’affiche en moins de N secondes dans 99% des cas, les autres pages répondent un code HTTP 20X : ce type de validation est à mettre si le contrat précise des temps de réponses sur certaines pages clef.
  • Le batch de N lignes est intégré en moins de X minutes et on retrouve les N lignes en base de données.

1.3 Plateforme

Il faut prévoir un environnement sur lequel lancer les tests de performance.

Dans cette partie, il faut aussi préciser les services qui seront vraiment utilisés et ceux qui seront bouchonnés ou simulés. Il est préférable de commencer par les tests sur la partie sur laquelle vous avez la responsabilité et puis ensuite ouvrir les liaisons avec des services tiers, s’il reste du temps et que les services tiers l’acceptent.

Il faut détailler un minimum comment sont fait les bouchons, par exemple :

  • données en dur dans le code
  • service de bouchon qui simule des réponses

Pour le choix de la plateforme :

  • L’application n’est pas encore ouverte en production et la plateforme de production est prête : vous êtes dans les meilleures conditions, vous allez vraiment tester les performance sur la plateforme cible.
  • Sinon il faut chercher un environnement équivalent, et éventuellement faire des hypothèses. Par exemple si vous avez une pré-production avec 2 fois moins de machines, tester avec la moitié de la volumétrie attendue et prendre l’hypothèse que deux fois plus de machines supporterons deux fois plus de flux. A noter que rien ne garantit que l’impact de la charge soit linéaire : tester la moitié de la charge sur une demi-plateforme permet de se rassurer mais pas de complètement valider les performance de la production. Si possible, il vaut mieux tester avec bien plus que la moitié de la volumétrie, voir même la charge complète.
  • Au pire, sur un PC de développement, ce n’est vraiment pas optimal mais on peut quand même trouver pas mal de points de contentions et anticiper un minimum la production. Dans ce cas-là il faut bien marquer dans le document que le test de performance réalisé est loin de simuler la production afin que le risque soit partagé par tous les acteurs du projet.

A noter que seule la production permet de faire des tests totalement représentatif de la réalité. Les autres environnements sont utilisées en solution de repli quand il n’est vraiment pas possible de réaliser les tests sur la production.

A titre d’illustration je vais citer l’allégorie mécanique de Valery Brasseur.

« Si on prend un environnement à l’échelle, ça suffira ! » Eh bien, non ! Pourquoi ?

Prenons l’exemple d’une voiture et de son moteur. Imaginons, que la voiture aille à 100Km/h en production. Et mettons que l’on fasse nos tests à l’échelle ¼, cela veut-dire que la voiture sera limité à 25km/h, mais le reste n’aura pas changé ! Si le problème apparait à 30km/h on ne le verra jamais.

Le problème est d’ailleurs plus compliqué encore car le système est composé de multiples éléments et la mise à l’échelle ne s’applique hélas pas à tous de la même façon. Il faut donc aussi faire attention à la manière dont la mise à l’échelle s’applique voir à certains éléments « insécables » (par exemple : un firewall, la bande passante, un load balancer etc.). En clair, il est important de pouvoir tester « grandeur nature », et a tous le moindre, le faire au moins une fois avant la mise en production.

De même, si nous sommes forcé d’avoir un environnement « à l’échelle », il faudra faire attention aux facteurs dimensionnant, exemple : si on diminue le nombre de middle mais pas la BDD, on se retrouve avec « une deux-chevaux avec un moteur de Ferrari », et on ne verra jamais les problèmes de BDD (surchauffe moteur ;-)

1.4 Hypothèses et volumétrie

Si vous ne savez pas quelle unité utiliser, prenez la volumétrie par minutes, c’est ce qui est le plus facile à vérifier quelle que soit la durée du tir. Par exemple si vous commencez par un tir de 10 minutes pour valider le scénario, vous pourrez rapidement vous rendre compte si vous êtes proche de la volumétrie cible par minutes ou pas. Lors des premiers tirs, il est courant d’être très loin de la volumétrie cible : soit les requêtes sont bien trop espacées, soit bien trop rapprochées.

Pour un projet existant, vous pouvez constater la volumétrie réelle directement avec les mesures que vous avez de la production, par exemple :

  • Le nombre de requêtes ou pages par minutes sur les logs apaches ou nginx ou autre point d’entrée ;
  • Les requêtes ou pages les plus utilisées ;
  • La taille des fichiers échangés pour les batchs ;
  • Le nombre d’utilisateurs en base de données.

Pour un nouveau projet, c’est souvent un peu plus compliqué, à moins d’être clairement engagé sur une volumétrie dans le contrat en action par minutes ou secondes. Il faut essayer d’obtenir des personnes responsables du fonctionnel, le nombre d’utilisateurs « simultanés », les pics de fréquentation envisagés, la rapidité d’exécution de la tâche par un “humain” pour les sites web ou un “objet” pour les échanges de machine à machine.

Dans tous les cas, il faut bien partager les hypothèses de volumétrie avec tous les acteurs du projet.

Vous pouvez aussi dans cette partie expliquer les simplifications ou hypothèses communes à tous les scénarios, par exemple si on considère que 20% des utilisateurs qui constituent un panier vont jusqu’au paiement dans un site de e-commerce.

2 Scénarios utilisés

Le but de cette partie est de décrire en détail les scénarios utilisés pour les tests de performance. L’idéal est de coller à des scénarios fonctionnels réels, sachant qu’ensuite plusieurs scénarios peuvent être utilisés dans un seul tir.

L’avantage d’avoir un découpage en scénario fonctionnel, est de pouvoir ensuite changer les volumétries par exemple :

  • un tir avec 20% d’utilisateurs qui souscrivent au service X, et 80% qui utilisent le simulateur de YY
  • un tir avec 50% d’utilisateurs qui souscrivent au service X, et 50% qui utilisent le simulateur de YY + quelques agents en back-office

2.1 Scénario [Nom du scénario]

Il est intéressant de mettre une référence de scénario courte, pour pouvoir ensuite la réutiliser dans la description d’un tir, le framework de test de performance ou faire un lien dans des spécifications projet.

2.1.1 Description fonctionnelle du scénario

Description fonctionnelle et détaillée du scénario, par exemple :

  • l’utilisateur se connecte sur la page de login
  • il saisit son login, mot de passe et valide
  • il est ensuite redirigé vers son compte
  • il choisit dans le menu à gauche d’afficher sa messagerie
2.1.2 Données d’entrée

Description du jeu de données utilisé, ainsi que des données figées ou générées aléatoirement par exemple :

  • le login et mot de passe des utilisateurs est pris au hasard dans un fichier CSV contenant 200 comptes utilisateurs actifs
  • la géolocalisation donnée par le téléphone est simulée par un nombre au hasard dans un rectangle ayant pour coordonnées : [(46.188060, 6.229955) (46.188060, 6.243109) (46.198028, 6.243109) (46.198028, 6.229955)]
  • 50% des user agent correspondent à un iPhone et 50% à Android
2.13 Vérifications en fin de tir

Le but est de se mettre d’accord avant de commencer les tests sur les métriques qui vont valider les tests. Selon la métrique à valider, il faudra mettre en place plus ou moins d’outils de mesure.

Par exemple si la seule réponse HTTP suffit, en général les framework de test de performance permettent de l’avoir directement. Par contre si on veut valider des metriques système comme le CPU, RAM ou le nombre d’IO, il faut s’assurer avant de pouvoir collecter facilement les données pour les analyser en fin de tir.

Le but est aussi de partager avec l’ensemble des acteurs du projet et de façon exhaustive l’ensemble des indicateurs qui seront surveillés.

3 Tirs et résultat

Cette partie permet de garder une trace pérène des tests effectués et des résultats obtenus à date.

3.1 Tir du JJ/MM/AAAA

3.1.1 Contexte du tir

Pour chaque tir, il faut détailler :

  • le ou les scénarios utilisés
  • la durée du tir
  • la montée en charge progressive ou non

Je conseille d’aller crescendo sur les tests de performance, et de toujours commencer par faire un tir par scénario. Et lorsque chaque scénario est passé avec succès de façon individuelle, de mélanger les scénario pour se rapprocher de la simulation cible.

3.1.2 Résultats et relevés

Cette partie permet de valider que le tir réel est conforme au tir attendu. Il est important de vérifier que la volumétrie réellement injectée correspond à celle qui était attendue. Selon les cas il peut être difficile de reproduire une volumétrie avec précision.

Par exemple :

Il y a eu 7042 utilisateurs simulés en 1h dont :

  • 2359 ont acheté les articles déposés dans le panier (soit environ 39 achats / minute)
  • 2355 ont ajouté des articles au panier sans la commande
  • 2328 n’ont rien mis dans leur panier

Cette partie permet aussi de rassembler les différentes métriques relevées, ou au moins les résultats agrégés.

Par exemple :

  • Nombre de requêtes en erreur : 0
  • Nombre de requêtes < 3s : 15 320 soit 97,3 % des requêtes
  • Nombre de requêtes < 3s : 423
3.1.3 Conclusion

L’objectif de cette partie est de constater clairement si :

  • le tir est considéré comme valide, et les résultats des tests sont conformes à l’attendu
  • les résultats des tests sont non conformes, auquel cas il faudra apporter des modifications de code et de configuration à l’application puis relancer exactement le même tir pour comparer
  • éventuellement si les résultats sont conformes mais avec quelques réserves

En cas d’échec de validation des performance, ils est important de conserver toutes les informations sur le tir en échec pour pouvoir démontrer que les corrections mises en place corrigent bien le problème détecté à l’origine.

Et sinon, des outils à proposer ?

Gatling

Gatling logo

Je ne prétends pas connaitre tous les outils de test de performance, mais en ce moment mon outil préféré pour les tests de site web est Gatling.

Pour plusieurs raisons, en voici les principales :

  • il est open source
  • il se lance très facilement avec Maven (ou Graddle) mvn gatling:test
  • les résultats par défaut sous forme de site statique html sont de bonne qualité et exportable tels quels à vos clients, chef de projet, directeur de projet, etc.
  • on arrive rapidement à le lancer avec peu de code et en utilisant les options par défaut
  • il y a un enregistreur de requêtes “recorder” qui se met en proxy d’un navigateur et permet de générer le code pour les scénario
  • les méthodes sont vraiment en phase avec le language des tests de performance, tels que la notion de scénario, d’utilisateur, de rampe de lancement, de prise de donnée aléatoire dans un CSV
  • l’injecteur est très performant, je n’ai pas encore rencontré de cas où il m’a fallu lancer plusieurs Gatling en parrallèle pour arriver à simuler la charge cible.

Ma plus grande difficulté avec Gatling est l’usage du langage Scala. Je n’avais jamais fait de Scala auparavant et ce language n’est pas très répandu dans les équipes autour de moi.

Apache bench

Si vous n’avez besoin de lancer des tests que sur une seule URL, je vous conseille de regarder du côté d’apache bench, dont l’usage est très simple :

ab -n 100 -c 10 "http://mapage.com"

La commande ci dessus va lancer 100 requêtes avec 10 clients (utilisateurs) sur http://mapage.com

Jeu de données

Quand c’est possible le plus simple est d’utiliser l’aléatoire, par exemple pour avoir un point cardinal on peut très bien prendre au hasard parmi {Sud, Nord, Est, Ouest}. Mais parfois il est nécessaire d’utiliser des données un peu plus complexes telles que des noms/prénoms ou des adresses.

Pour ce qui est des données “classiques” telles que des noms, prénoms, adresse postales il est possible de profiter de l’open data.

Par exemple pour des noms/prénoms il m’est arrivé d’utiliser le CSV de la liste des députés. On peut trouver beaucoup de type de données différentes en open data et avec un peu d’imagination créer des jeux de données.

Il existe aussi des sites de génération de données comme Fake name generator.

Conclusion

Si vous ne retenez que deux choses :

Les tests de performance c’est l’affaire de tous !

Et

Les tests de performance se préparent dès le début du projet !

Amusez-vous bien :)

Crédits images: Pixabay


Written by

Angélique Henry

Mac gyver de l'IT, et Duchesse Lyonnaise