JMeter – Variabilisation de données

Revu et mis à jour le 20 juin 2010 avec JMeter 2.4 (version développement révision 951940) en version française.

Pour ce tutoriel, nous allons voir comment variabiliser des données saisies par formulaire pour effectuer un tir de charges avec JMeter avec des données changeantes à chaque itération du tir. La variabilisation des données permet de mieux simuler la diversité de requêtes que l’on peut avoir sur un environnement réel. Notamment en évitant les effets de cache (navigateur, persistance, etc).

Pour ce tutoriel, on suppose que vous avez déjà effectué le tutoriel sur l’enregistrement d’un scénario fonctionnel dans JMeter.

Par ailleurs, on reprend les servlets d’exemples de Tomcat 5.5 comme « site Web modèle », et on utilise la version 2.3 2.4 (dev) de JMeter.

Identification du scénario fonctionnel

La première étape consiste à identifier le scénario fonctionnel.

Ecran 1 : la page d’accueil des servlets d’exemples de Tomcat

Ecran 1 : la page d'accueil des servlets d'exemples de Tomcat

On fait défiler la page vers le bas, pour voir la liste des servlets disponibles.

clique sur le lien Execute de la servlet d'exemple Request Headers

On clique sur le lien Execute de la servlet d’exemple Request Headers pour arriver sur l’écran suivant.

Ecran 2 : Formulaire Request Headers

Ecran 2 : Formulaire Request Headers

Ecran 3 : Saisie du nom et prénom.

Ecran 3 : Saisie du nom et prénom.

Puis on clique sur le bouton Submit Query pour envoyer les données du formulaire.

Ecran 4 : Résultat du formulaire

Ecran 4 : Résultat du formulaire

Les données envoyées apparaissent en haut dans le formulaire. Ensuite on clique que la flèche de retour pour revenir à la page d’accueil des servlets de test de Tomcat.

Ecran 5 : Retour à la page d’accueil

Ecran 5 : Retour à la page d'accueil

Et voilà, nous avons maintenant un scénario fonctionnel. Il reste simple et démonstratif. Il reste à le « Jmeteriser » en suivant la méthode de ce tutorial (utilisation de l’item HTTP Proxy).

Voici, ci-dessous, le résultat de la Jmeterisation.

Scénario du tir

Allons voir du coté de la requête HTTP numéro 03, correspondant à l’envoi des données du formulaire.

Exemple de données envoyées par formulaire

On retrouve dans la section Envoyer les paramètres avec la requête, les paramètres correspondant aux champs Prénom (firstname) et Nom (lastname) du formulaire. Ce sont ces paramètres que nous allons « variabiliser ».

Variabilisation du scénario

Pour variabliser le scénario, nous allons mettre de coté JMeter un instant, et commencer la préparation d’un fichier au format CSV (texte séparé par des virgules). Ce fichier sera « l’input » de JMeter pour faire tourner la valeur des champs Nom et Prénom.

Pour réaliser ce fichier, une méthode consiste à prendre un tableur comme Excel ou comme ici, Calc d’OpenOffice. La première colonne sera le prénom, et la deuxième colonne sera le nom. (Ici c’est une liste de boxeurs.)

La liste dans OpenOffice Calc

Une fois que la liste est prête, il faut l’enregistrer avec le format CSV, en changeant le type du fichier à partir de la liste déroulante sous le nom du fichier.

Nom de fichier et extension CSV

OpenOffice Calc permet de choisir le charset, le délimiteur de champ et le délimiteur de texte. On choisira de préférence UTF-8, le délimiteur de champ est bien sûr la virgule et on laissera le champ délimiteur de texte à vide.

Format d'enregistrement du fichier CSV

Nous avons donc maintenant un fichier CSV prêt pour être l’input de Jmeter.

Revenons donc vers JMeter, on sélectionne l’élément Groupe d’unités, et on ajoute un élément de configuration Source de données CSV.

Ajout de l'item CSV Data Set Config

L’élément Source de données CSV permet de lire un fichier CSV et de mettre dans une ou plusieurs variables JMeter provenant d’une ligne dudit fichier. A chaque itération, la ligne suivante est sélectionnée.

Configuration de l'item CSV Data Set Config

On saisie les valeurs suivantes dans les champs :

  • Nom de fichier : le chemin absolu et le nom du fichier. (ou bien juste le nom du fichier, auquel cas le fichier doit se trouver dans le classpath de Jmeter. Par exemple : JMETER_HOME/bin)
  • Encodage du fichier : Lors de l’export du fichier CSV avec Calc, le format UTF-8 a été choisi, donc on reprend la même chose.
  • Noms des variables : le nom des variables dans lesquelles JMeter va insérer les éléments d’une ligne. Dans le fichier CSV, la première colonne était le prénom, la seconde était le nom, donc on saisie « PRENOM,NOM » pour avoir dans la variable PRENOM le prénom, et dans la variable NOM le nom.
  • Délimiteur : on travaille avec un fichier « pur » CSV, et donc c’est la virgule qui nous sert de séparateur de champ.
  • Recycler en fichier de fichier ? : Est-ce qu’à la fin du fichier (End Of File), JMeter reprend la liste depuis le début pour variabiliser les variables ? Oui pour nous.
  • Arrêter l’unité à la fin du fichier ? : Est-ce que l’élément Groupe d’unités dans lequel se trouve l’élément Source de données CSV se stoppe à la fin du fichier, quelque soit le nombre d’itérations prévu ? Non pour nous

Maintenant que nous avons complété l’élément Source de données CSV, nous disposons de deux variables pendant l’exécution du test de charge. Nous allons les utiliser dans notre scénario de tir. Pour cela, on se positionne sur l’élément Requête HTTP numéro 03, celui qui correspond à l’envoi de données de la servlet Request Param.

Mise en place des variables JMeter pour l'insertion des données

Dans la zone Envoyer les paramètres avec la requête, on retrouve les noms HTML des champs du formulaire : firstname et lastname. Dans la colonne Valeur, nous allons remplacer les valeurs données lors de l’enregistrement du scénario par : ${PRENOM} et ${NOM}. Le ${…} indique à JMeter qu’il s’agit d’une variable, et que lors de l’exécution, il faut la remplacer par la valeur de la variable.

Allons un peu plus loin, pour cela autant vérifier que les données variabilisées envoyées (beaucoup de « ées » :-)) sont bien celles qui sont affichées dans la réponse. Ainsi on va chercher l’élément Assertion Réponse de l’élément Requête HTTP numéro 03.

Configuration du test d'assertion

En utilisant le bouton Ajouter, on va ajouter deux Motifs à tester : ${PRENOM} et ${NOM} tout simplement. Si JMeter trouve les deux dans la réponse HTML reçue, alors l’assertion est OK.

Exécution du tir

Et voilà, maintenant nous sommes prêt pour exécuter le tir. On se place sur l’élément Groupe d’unités, on choisit les paramètres du Groupe d’unités, ici un seul utilisateur virtuel, sur une période de montée en charge de 1 sec, qui va exécuter 400 fois le scénario.

Configuration du tir de charges

On lance le tir, avec le raccourci clavier Ctrl + R (ou le menu Lancer > Démarrer), le résultat (ci-dessous) visible sur l’élément Rapport consolidé :

Rapport d'exécution du tir

On note qu’il n’y a pas d’erreurs dans le tir, notamment sur la Requête HTTP numéro 03. On peut aussi vérifier que tout s’est bien passé en allant voir l’élément Arbre de résultats.

Réponse HTML d'un premier cas

En choisissant au hasard une requête 03, dans l’onglet Données de réponse, on retrouve bien le nom d’un boxeur au lieu des variables ${PRENOM} et ${NOM}.

Réponse HTML d'un deuxième cas

Et si on va sur une autre requête 03, le prénom et le nom sont bien différents. C’est gagné, la variabilisation marche ! (mais qui en doutait ?). Nous avons vu dans ce petit tutoriel comment variabiliser les données entrées par formulaire dans un site Web.

Quelques remarques :

L’élément Source de données CSV est très pratique pour cette action, mais d’autres moyens permettent de faire la même chose, cependant plus difficilement (en l’occurrence, il s’agit des fonctions JMeter __CSVRead() et __StringFromFile()).

Ce tutoriel montre la variabilisation à partir de données « connues » avant le tir. Il est aussi possible de variabiliser un scénario de tir avec des données
retrouvées (ou calculées) dynamiquement pendant l’exécution du tir. (On utilisera en autre l’élément Extracteur d’expression régulière du groupe Post-processeurs pour ce genre de cas. Voir ce billet)

La petite astuce de la fin :

JMeter possède un fichier principal de paramètres, placé dans JMETER_HOME/bin. Ce fichier s’appelle jmeter.properties. Vous trouverez dedans le paramètre proxy.number.requests qui permet d’avoir une numérotation automatique des éléments Requête HTTP lors d’un enregistrement via l’élément Proxy HTTP. Il faut donner la valeur true pour avoir la numérotation automatique, et redémarrer JMeter.

proxy.number.requests=true

A bientôt pour de nouvelles aventures…

10 réflexions au sujet de « JMeter – Variabilisation de données »

  1. Bonjour à toi,

    Tout d’abord merci pour cet article qui m’a été fort utile, pour les tests que j’effectue en ce moment sur une appli java.
    J’ai tout de même une petite question :

    J’ai un script qui me permet d’uploader un fichier sur un serveur.
    En enregistrant le scénario avec JMeter, l’url du fichier apparait bien dans la section : « Send Files With The Request ».

    Je souhaiterai en fait « variabiliser » cette url, via un fichier CVS (que j’ai ajouté à JMeter). Cependant, où dois-je renseigner ma variable pour rendre l’url dynamique ? (J’ai essayé de remplacer l’url par le nom de la variable, mais aucun résultat.)

    Merci d’avance pour ta réponse.

    @+ 🙂

  2. Merci.
    Oui tu dois mettre le nom de ta variable dans le champ « File Path: » de l’élément HTTP Request.
    As-tu bien mis en POST (et non GET) la méthode de connexion dans cet élément?

  3. Oui, j’utilise bien la méthode ‘POST’. Mais c’est bon tout marche maintenant. En fait c’était une erreur toute bête!
    Dans la config de mon CSV_DATA_CONFIG, mon champ « File encoding » était à « UTF_8 » au lieu de « UTF-8 » … -_-‘

    Merci tout de même pour tes petites indications 🙂

  4. Bonjour,

    Quel plaisir de lire du francais a propos de Jmeter : MERCI.

    Je me heurte a un probleme de path absolu/relatif dans l’envoi d’un fichier.
    Mon csv contient juste le filename, et j’aimerais construire mon path selon le model /Corpus/${FILENAME}.

    -> Problème, j’obtiens un java.io.FileNotFoundException: \Corpus\MonFileName

    Je passe mon path csv en relatif : le répertoire du jmx faisant office de base, il le comprend bien, pourquoi n’en est il pas de même pour envoyer un fichier dans la requete ?

    Tu dis dans ton article chemin absolu ou path jmeter… il n’y a pas une astuce pour construire en relatif (sans renseigner un path en variable globale en tout début bien sur…)

    Merci pour tout

    @+

    Fabrice

  5. De rien 🙂 pour le français, j’espère que le mixte des captures en anglais et le texte en français n’est pas trop pénible. Pour ma part je préfère garder le vocabulaire anglais pour plus de faciliter dans les recherches de résolution de problème (via google.com)

    Pour répondre à ta question, malheureusement les deux champs de « fichier » (celui du CSV Data Set Config et celui du HTTP Sampler (Send Files With the Request)) sont lus différemment dans JMeter.

    Celui du CSV Data Set Config, est lu (ouvert) à travers un processus interne Jmeter de « serveur de fichiers » (un méchanisme de singleton) qui teste le nom de fichier (filename) passé en paramètre pour déterminer si c’est un chemin absolue ou relatif.
    Celui du HTTP Sampler, est lu directement sans test de nom de fichier et contrôle particulier sur le filename donné (il faut juste qu’il soit non-vide – 0 caractère).
    Ce qui explique le comportement différent des deux champs filename (celui de mon billet ci-dessus étant le CSV Data Set Config).

    Il est donc obligatoire de fournir un chemin relatif pour ce filename (à moins de faire une demande d’évolution sur le bugzilla de Jmeter)
    Je ne sais pas quelles sont tes contraintes sur ce/ces fichier(s) et leur chemin d’accès. Je suppose que ce n’est pas possible pour toi d’avoir le chemin absolu ?

    Néanmoins, tu peux « variabiliser » la racine de chemin absolu à travers la mise en place d’une propriété Java (en ligne de commande (/usr/loca/bin/jmeter -Duser.monchemin=/home/milamber -n -t TestPlan.jmx -l resultats.jtl) ou dans le fichier user.properties (ex. user.monchemin=/home/milamber)

    La valeur à mettre dans le champ « File Path: » du HTTP Request est alors :
    ${__P(user.monchemin,ERREUR_CHEMIN_ABSOLU_NON_DEFINI)}/${NOM_FICHIER}

    (si tu es sous Linux/Unix/Cygwin), En combinant avec la commande `pwd` (sous unix, pwd renvoi le chemin courant) tu peux le rendre ‘dynamique’ :
    /usr/local/bin/jmeter -Duser.monchemin=`pwd` -n -t TestPlan.jmx -l resultats.jtl
    (je viens de tester avec succès :-))

    A+

  6. Salut,

    Merci pour cette confirmation. Ma contrainte est de livré clef en main a des gens qui ne sont pas forcement apte ou qui ne veulent pas avoir de paramétrage a faire, c’est pourquoi je voulais construire en relatif depuis le répertoire qu’ils dézippent et tout est jouable directement.
    Bref ce n’est pas grave, il ont une variable a renseigner avant d’exécuter le jmx, c’est très simple ca devrait aller.

    Merci de toutes ces informations, façons de faire : c’est parfait.

    Bon courage

    Fabrice

  7. Bonjour,

    en partant d’un scénario tout simple (identification + mot de passe sur un site puis déconnexion du site), j’aimerais savoir si variabliser le champ « User » et le champ « Password » ne poserait pas de problème? Car j’ai bien effectué toute les étapes du tutoriel mais celui m’affiche une erreur au niveau du User alors que celui-ci est bien correct. Je précise que le dans le champ mot de passe, il y a la case encoder qui est cochée.

    Merci d’avance.

    DaddyP

  8. Pour réaliser un tir avec des injecteurs sous Windows et d’autres sous Linux, une difficulté est d’avoir des repetoires differents contenant le fichier de parametres (par exemple sous Windows C:/Temp/liste_login.csv et sous Linux /var/liste_login.csv).

    Voici une solution technique :
    Sous le test plan, créer un Source de données CSV et dans le nom (name) mettre un script beanshell qui teste le nom de l’OS et qui définie une properties avec une valeur différentes en fonction de l’OS.

    Par exemple le champ name contient un beansheel avec un test ternaire :
    ${__BeanShell(sOs = System.getProperty(« os.name »);(sOs.contains(« Windows »)) ? props.setProperty(« P_FIC_PARAM » \, « c:/Temp/liste_login.csv ») : props.setProperty(« P_FIC_PARAM » \, « /var/liste_login.csv ») )}

    Le champs nom de fichier contient la valeur de property initialisee dans le beanshell :
    ${__P(P_FIC_PARAM)}

    On peut faire un peu plus complet avec des If
    ${__BeanShell(sOs = System.getProperty(« os.name »); if (sOs.contains(« Windows »)) { print(« sOs source csv =  » + sOs); props.setProperty(« P_FIC_PARAM » \, « c:/Temp/liste_login.csv »); } if (sOs.contains(« Linux »)) { print(« sOs source csv =  » + sOs); props.setProperty(« P_FIC_PARAM » \, «  »/var/liste_login.csv »); } )}

    On faut faire attention au caractere virgule qui doit etre despecialise ex: \,
    Il faut aussi penser à copier « manuellement » le fichier de parametre dans le bon repertoire avant de lancer le tir.

    Cordialement
    Vincent

Les commentaires sont fermés.