Artillery est un outil de test de charge open-source basé sur Node.js. Il génère un trafic concurrent vers votre API à partir d’un script YAML : vous définissez des phases de charge, des scénarios HTTP, puis vous lancez artillery run script.yml. Artillery mesure ensuite les percentiles de latence, le débit de requêtes et les erreurs. Ce guide montre comment installer Artillery v2, écrire un test réaliste, l’exécuter, exporter les résultats au format v2 actuel et l’intégrer dans une CI.
Ce qu’est Artillery et quand l’utiliser
Artillery simule des utilisateurs virtuels qui appellent vos endpoints comme le ferait un client réel. Chaque utilisateur virtuel exécute un scénario : une suite de requêtes HTTP, dans un ordre défini.
Utilisez Artillery pour répondre à des questions de performance concrètes :
- Que devient la latence p95 à 50 requêtes par seconde ?
- À partir de quel taux d’arrivée les erreurs apparaissent-elles ?
- L’API reste-t-elle stable pendant 5 minutes de charge soutenue ?
- Le temps de réponse p99 augmente-t-il progressivement sous pression ?
Artillery est pratique parce que le test est déclaratif. Vous décrivez la charge en YAML au lieu d’écrire manuellement une boucle de concurrence. Comme il fonctionne avec Node.js, le même script peut tourner en local, en staging ou dans une CI.
Artillery n’est pas le seul outil de test de charge. Si vous comparez encore les options, consultez le tour d’horizon des meilleurs outils de test de charge et cette comparaison de logiciels de test de charge, qui couvrent k6, JMeter, Gatling et d’autres solutions.
Installer Artillery v2
Le package npm s’appelle artillery. Installez la dernière version globalement, puis vérifiez l’installation :
npm install -g artillery@latest
artillery version
Vous avez besoin d’une version LTS récente de Node.js. Artillery fonctionne sur Windows, macOS et Linux.
Si vous préférez éviter une installation globale, utilisez npx :
npx artillery@latest run script.yml
Écrire un script de test Artillery
Un script Artillery est un fichier YAML avec deux blocs principaux :
-
config: cible, phases de charge, variables, données de test. -
scenarios: actions exécutées par chaque utilisateur virtuel.
Voici un exemple complet avec trois phases : échauffement, montée en charge, puis charge soutenue.
config:
target: "https://api.example.com"
phases:
- name: "Warm up"
duration: 60
arrivalRate: 5
- name: "Ramp to peak"
duration: 120
arrivalRate: 5
rampTo: 50
- name: "Sustained load"
duration: 300
arrivalRate: 50
maxVusers: 500
# Variables inline, ou CSV via config.payload
variables:
productId:
- "1001"
- "1002"
scenarios:
- name: "Browse and create order"
flow:
- get:
url: "/v1/products/{{ productId }}"
- post:
url: "/v1/orders"
json:
productId: "{{ productId }}"
quantity: 2
Comprendre config
config.target définit l’hôte de base. Chaque url du scénario est ajoutée à cette base.
Exemple :
target: "https://api.example.com"
Avec cette étape :
- get:
url: "/v1/products/1001"
Artillery appelle :
https://api.example.com/v1/products/1001
config.phases décrit la forme de la charge. Les options les plus utilisées sont :
-
duration: durée de la phase, en secondes ou sous forme lisible comme"5m". -
arrivalRate: nombre de nouveaux utilisateurs virtuels créés par seconde. -
rampTo: augmentation linéaire dearrivalRatejusqu’à cette valeur. -
arrivalCount: nombre fixe d’utilisateurs virtuels répartis sur la phase. -
maxVusers: plafond d’utilisateurs virtuels simultanés. -
name: nom affiché dans les résultats.
Point important : duration contrôle la durée pendant laquelle Artillery crée de nouveaux utilisateurs virtuels. Ce n’est pas forcément la durée totale réelle du test. Si un utilisateur virtuel démarre à la fin d’une phase et que son scénario prend du temps, Artillery attend qu’il termine.
Comprendre scenarios
scenarios est un tableau. Chaque scénario contient un flow, c’est-à-dire la liste ordonnée des actions exécutées par un utilisateur virtuel.
Exemple minimal :
scenarios:
- name: "Health check"
flow:
- get:
url: "/health"
Vous pouvez définir plusieurs scénarios et utiliser weight pour contrôler leur probabilité relative :
scenarios:
- name: "Browse products"
weight: 80
flow:
- get:
url: "/v1/products"
- name: "Create order"
weight: 20
flow:
- post:
url: "/v1/orders"
json:
productId: "1001"
quantity: 1
Les étapes HTTP utilisent les verbes :
getpostputpatchdelete
Les corps JSON se déclarent sous json. Les variables utilisent la syntaxe {{ variableName }}.
Alimenter le test avec un CSV
Pour un test de fumée, des valeurs codées en dur suffisent. Pour une charge plus réaliste, utilisez config.payload avec un fichier CSV.
Exemple users.csv :
email,password
alice@example.com,password1
bob@example.com,password2
Script Artillery :
config:
target: "https://api.example.com"
payload:
path: "./users.csv"
fields:
- "email"
- "password"
phases:
- duration: 120
arrivalRate: 20
scenarios:
- flow:
- post:
url: "/login"
json:
email: "{{ email }}"
password: "{{ password }}"
Chaque utilisateur virtuel récupère une ligne du CSV. Les colonnes deviennent des variables disponibles dans le scénario.
Exécuter le test
Commande de base :
artillery run script.yml
Changer la cible sans modifier le fichier :
artillery run --target https://staging.example.com script.yml
Passer des variables en JSON :
artillery run -v '{ "productId": ["1001","1002"] }' script.yml
Options utiles :
-
--targetou-t: remplaceconfig.target. -
--environmentou-e: sélectionne un environnement défini dansconfig.environments. -
--configou-c: charge une configuration depuis un fichier séparé. -
--insecureou-k: ignore la vérification TLS, utile avec des certificats auto-signés en environnement de test.
Exemple avec environnements :
config:
target: "https://api.example.com"
environments:
staging:
target: "https://staging.example.com"
production:
target: "https://api.example.com"
phases:
- duration: 60
arrivalRate: 10
scenarios:
- flow:
- get:
url: "/health"
Exécution :
artillery run -e staging script.yml
Lire les résultats
Pendant l’exécution, Artillery affiche des métriques agrégées environ toutes les 10 secondes. À la fin, il affiche un résumé.
Surveillez en priorité :
- Débit réel : nombre de requêtes par seconde effectivement atteint.
- Latence p50 : médiane des temps de réponse.
- Latence p95 : temps sous lequel 95 % des requêtes terminent.
- Latence p99 : temps sous lequel 99 % des requêtes terminent.
- Erreurs : timeouts, réponses non-2xx, erreurs réseau, échecs applicatifs.
Ne vous limitez pas à la moyenne. Une moyenne peut rester correcte alors que la p99 dérive vers plusieurs secondes. La latence de queue est souvent le premier signal d’un point de saturation.
Si les erreurs apparaissent uniquement pendant la phase soutenue, le système atteint probablement une limite : pool de connexions, base de données, CPU, mémoire, file d’attente ou dépendance externe.
Pour approfondir les métriques de performance API, consultez ce guide de test de performance API.
Générer un rapport avec Artillery v2
La génération de rapports a changé dans Artillery v2. Beaucoup d’anciens tutoriels indiquent encore :
artillery run --output report.json script.yml
artillery report report.json
La première commande reste valide. La seconde ne l’est plus.
--output écrit toujours un fichier JSON exploitable par machine :
artillery run --output report.json script.yml
En revanche, la commande artillery report, qui convertissait le JSON en HTML, a été supprimée de la CLI Artillery. La documentation officielle indique qu’elle n’est plus prise en charge. N’utilisez donc pas :
artillery report report.json
Sur Artillery v2 actuel, cette commande ne doit pas faire partie de votre workflow.
Vous avez trois approches valides.
Option 1 : analyser le JSON avec jq
C’est l’option la plus simple pour la CI.
Extraire la p95 agrégée :
jq '.aggregate.summaries["http.response_time"].p95' report.json
Exemple de garde-fou CI : échouer si la p95 dépasse 500 ms.
P95=$(jq '.aggregate.summaries["http.response_time"].p95' report.json)
echo "p95=${P95}ms"
if (( $(echo "$P95 > 500" | bc -l) )); then
echo "La latence p95 dépasse le budget de 500 ms"
exit 1
fi
Option 2 : utiliser Artillery Cloud
Artillery Cloud remplace l’ancien rapport HTML pour obtenir un tableau de bord hébergé.
artillery run --record --key $ARTILLERY_CLOUD_API_KEY script.yml
Option 3 : publier les métriques dans votre observabilité
Vous pouvez pousser les métriques vers votre pile existante avec le plugin publish-metrics ou OpenTelemetry. C’est utile si vous voulez corréler les résultats de charge avec les métriques applicatives, base de données ou infrastructure.
Exécuter Artillery en CI
Artillery étant une CLI Node.js, il s’intègre facilement dans GitHub Actions, GitLab CI, CircleCI ou Jenkins.
Voici un workflow GitHub Actions qui :
- installe Node.js ;
- installe Artillery ;
- exécute le test ;
- exporte
report.json; - sauvegarde le rapport comme artefact.
name: Load test
on: [workflow_dispatch]
jobs:
artillery:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "lts/*"
- run: npm install -g artillery@latest
- run: artillery run --output report.json script.yml
- uses: actions/upload-artifact@v4
with:
name: artillery-report
path: report.json
Les tests de charge lourde ne doivent pas forcément tourner à chaque commit. Ils consomment du temps, de la bande passante et peuvent impacter des environnements partagés. Déclenchez-les plutôt :
- manuellement ;
- chaque nuit ;
- avant une release ;
- après un changement d’infrastructure ;
- après une modification critique de performance.
Vous pouvez ensuite ajouter une étape de validation de seuil.
- name: Check p95 latency
run: |
P95=$(jq '.aggregate.summaries["http.response_time"].p95' report.json)
echo "p95=${P95}ms"
if (( $(echo "$P95 > 500" | bc -l) )); then
echo "p95 trop élevée"
exit 1
fi
Où Apidog s’insère : tests fonctionnels et CI
Artillery répond à cette question :
L’API peut-elle supporter ce niveau de trafic ?
C’est du test de charge et de performance.
Une autre question doit être traitée en parallèle :
L’API renvoie-t-elle toujours les bonnes réponses après ce changement de code ?
C’est du test fonctionnel et de régression. C’est là que Apidog intervient.
Apidog est une plateforme API tout-en-un pour la conception, le débogage, le mocking, la documentation et les tests automatisés. Ses scénarios de test regroupent des endpoints en étapes logiques avec des conditions comme if, for et foreach. Vous pouvez valider :
- les codes HTTP ;
- les corps de réponse ;
- les contrats d’API ;
- les valeurs retournées ;
- les enchaînements entre endpoints.
Ces scénarios peuvent être exécutés en CI avec la CLI Apidog afin de bloquer une fusion si une régression fonctionnelle apparaît.
Soyons précis sur la limite : Apidog inclut une fonctionnalité de test de performance, mais elle est limitée à 100 utilisateurs virtuels maximum. C’est utile pour détecter des régressions évidentes, mais ce n’est pas un remplacement d’Artillery pour des tests de forte concurrence.
Pour une charge distribuée, scriptée et à grande échelle, Artillery reste l’outil approprié. Ce positionnement est aussi présenté dans l’article sur les tests de charge d’API sans Python, et la fonctionnalité 100 UV d’Apidog est détaillée dans les tests de performance API dans Apidog.
La combinaison recommandée :
- Artillery pour tester la charge, la latence et la saturation.
- Apidog CLI pour tester les comportements fonctionnels et les contrats en CI.
Installer et exécuter la CLI Apidog :
# Apidog CLI : exécution fonctionnelle/régression en CI
# La commande apidog run utilise uniquement des flags, sans fichier positionnel.
npm install -g apidog-cli
apidog run \
--access-token $APIDOG_ACCESS_TOKEN \
-t <TEST_SCENARIO_ID> \
-e <ENVIRONMENT_ID> \
-r cli,junit \
--out-dir ./apidog-reports
Paramètres importants :
-
--access-token: token d’accès Apidog. -
-t: ID du scénario de test. -
-e: ID d’environnement requis. -
-r cli,junit: sortie console + rapport JUnit XML. -
--out-dir: dossier de sortie des rapports.
Pour un guide détaillé, consultez le tutoriel CLI Apidog. Pour concevoir vos pipelines, consultez ces bonnes pratiques CI/CD pour les tests d’API.
Vous voulez que vos tests fonctionnels et contractuels contrôlent votre CI en parallèle de vos tests de charge Artillery ? Téléchargez Apidog gratuitement et créez votre premier scénario de test.
Questions fréquemment posées
Qu’est-ce que le test de charge Artillery ?
Le test de charge Artillery consiste à utiliser la boîte à outils open-source Artillery pour simuler de nombreux utilisateurs virtuels qui appellent votre API en concurrence. Vous décrivez la charge et le flux de requêtes dans un script YAML, vous l’exécutez, puis vous mesurez les percentiles de latence, les taux de requêtes et les erreurs.
Artillery est-il gratuit et open source ?
Oui. La CLI principale d’Artillery est gratuite et open source. Elle est distribuée sur npm via le package artillery. Artillery Cloud est une offre hébergée payante pour visualiser les résultats, mais vous pouvez exécuter des tests de charge localement et en CI sans l’utiliser.
Comment exécuter un test de charge Artillery ?
Installez Artillery :
npm install -g artillery@latest
Créez un fichier YAML avec :
- un bloc
configpour la cible et les phases ; - un bloc
scenariospour les requêtes.
Puis lancez :
artillery run script.yml
Artillery affiche des métriques en direct pendant l’exécution et un résumé à la fin.
Comment générer un rapport Artillery ?
Utilisez --output pour écrire un fichier JSON :
artillery run --output report.json script.yml
L’ancienne commande artillery report, qui produisait un rapport HTML, a été supprimée de la CLI Artillery. À la place, vous pouvez :
- analyser le JSON avec
jq; - utiliser Artillery Cloud avec
--record --key; - publier les métriques via
publish-metricsou OpenTelemetry.
Artillery vs k6 ou JMeter : lequel choisir ?
Les trois outils peuvent gérer des tests de charge à grande échelle.
- Artillery : YAML déclaratif, écosystème Node.js, simple à intégrer dans une CI JavaScript.
- k6 : scripts JavaScript avec une approche code-first.
- JMeter : outil Java avec interface graphique et vaste écosystème de plugins.
La comparaison Gatling vs JMeter couvre ces compromis plus en détail. Choisissez l’outil dont le modèle correspond à votre équipe, puis complétez-le avec des tests fonctionnels en CI pour couvrir à la fois la performance et la régression API.
Top comments (0)