Si votre API fonctionne bien pour un seul utilisateur mais s'effondre sous le trafic, vous avez besoin de tests de charge, et k6 est l'une des façons les plus simples de le faire. Ce guide explique ce qu'est k6, comment l'installer, comment écrire votre premier script et comment lire les résultats, afin que vous puissiez considérer les tests de charge comme faisant partie de votre routine normale de tests de performance d'API. Nous verrons également comment k6 s'intègre aux tests fonctionnels en CI, en nous appuyant sur la documentation officielle de k6 lorsque les détails sont importants.
Qu'est-ce que k6 ?
k6 est un outil de test de charge open-source, désormais maintenu par Grafana. Vous écrivez votre test sous forme de fichier JavaScript, k6 l'exécute avec un moteur Go rapide, et il soumet vos points de terminaison à un trafic simulé. La séparation est délibérée : vous rédigez des tests dans un langage que la plupart des développeurs connaissent déjà, mais le générateur de charge lui-même s'exécute en Go compilé, de sorte qu'une seule machine peut gérer un grand nombre d'utilisateurs virtuels sans s'essouffler.

k6 est conçu pour un seul objectif et le fait bien : générer une charge soutenue et reproductible et mesurer la façon dont votre système y répond. Il rapporte les centiles de latence, les taux de requêtes, les taux d'erreur et vous permet de définir des règles de réussite/échec sur ces chiffres. Cette focalisation est le point clé. k6 n'est pas un client API, un outil de documentation ou un framework de test fonctionnel. C'est un moteur de charge.
Quelques termes que vous rencontrerez constamment :
- Utilisateur virtuel (VU) : un utilisateur simulé exécutant votre script en boucle. Plus de VU signifie une charge concurrente plus élevée.
- Itération : un passage complet à travers votre fonction de test. Un VU exécute des itérations consécutives.
- Étape (Stage) : une étape dans un profil de charge, utilisée pour augmenter ou diminuer le nombre de VU au fil du temps.
- Seuil (Threshold) : une règle de réussite/échec sur une métrique, comme « le 95e centile de latence doit rester inférieur à 500ms ».
- Vérification (Check) : une assertion non fatale sur une réponse, comme « le statut était 200 ». Les vérifications échouées sont comptabilisées, mais le test continue de s'exécuter.
Installation de k6
k6 est livré sous la forme d'un unique binaire, l'installation est donc rapide. Sur macOS avec Homebrew :
brew install k6
Sur Windows avec Chocolatey :
choco install k6
Sur Debian ou Ubuntu, ajoutez le dépôt apt de Grafana et installez :
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg \
--keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" \
| sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
Confirmez que cela fonctionne :
k6 version
Une image Docker est également disponible si vous préférez ne rien installer localement. Consultez la page d'installation dans la documentation pour les commandes actuelles, car les détails des packages peuvent évoluer avec le temps.
Votre premier script k6
Un test k6 est un module JavaScript avec une fonction par défaut. k6 appelle cette fonction une fois par itération, par VU. Voici un script minimal qui cible un point de terminaison et vérifie la réponse :
import http from 'k6/http';
import { check, sleep } from 'k6';
export default function () {
const res = http.get('https://test-api.example.com/users');
check(res, {
'status is 200': (r) => r.status === 200,
'body is not empty': (r) => r.body.length > 0,
});
sleep(1);
}
Enregistrez-le sous le nom de script.js et exécutez-le :
k6 run script.js
Par défaut, k6 exécute un VU pour une itération. Le sleep(1) ajoute une pause d'une seconde entre les itérations, ce qui imite un utilisateur réel qui fait une pause entre les actions. Sans sommeil, chaque VU boucle aussi vite que le réseau le permet, ce qui est utile pour les tests de débit brut mais irréaliste pour la simulation du comportement de l'utilisateur.
Les appels check() sont des assertions souples. Une vérification échouée apparaît dans le résumé mais n'arrête pas l'exécution. C'est intentionnel. Sous une charge importante, vous vous attendez à des échecs, et vous voulez que le test continue de mesurer pour voir à quel point la situation se dégrade.
VU, étapes et seuils
Le premier script exécute un seul utilisateur une fois. Les tests de charge réels consistent à contrôler combien d'utilisateurs sollicitent votre API et pendant combien de temps. Vous configurez cela avec un objet options exporté.
La forme la plus simple définit un nombre fixe de VU et une durée :
export const options = {
vus: 50,
duration: '30s',
};
Cela exécute 50 utilisateurs virtuels pendant 30 secondes. Plus utile est un profil de montée en charge construit à partir d'étapes, qui vous permet de simuler un trafic augmentant, se maintenant et diminuant :
export const options = {
stages: [
{ duration: '1m', target: 100 }, // ramp up to 100 VUs
{ duration: '3m', target: 100 }, // hold at 100 VUs
{ duration: '1m', target: 0 }, // ramp down to 0
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% of requests under 500ms
http_req_failed: ['rate<0.01'], // less than 1% errors
},
};
Les seuils sont ce qui fait la force de k6 en CI. Si un seuil échoue, k6 se termine avec un code non nul. Cela signifie qu'une étape de pipeline peut faire échouer la construction lorsque les taux de latence ou d'erreur dépassent une limite que vous avez définie. Vous encodez un budget de performance sous forme de code, de la même manière que vous coderiez une assertion fonctionnelle.
Une carte rapide des profils de charge courants et de la question à laquelle chacun répond :
| Profil | Objectif | Ce que cela vous apprend |
|---|---|---|
| Smoke (Fumée) | Petite charge, vérifier que le script fonctionne | Le test lui-même est correct |
| Charge | Trafic normal attendu | L'API tient-elle le coup au quotidien |
| Stress | Dépasser le pic attendu | Où commence-t-elle à flancher |
| Spike (Pointe) | Saut soudain et brusque du nombre de VU | Peut-elle survivre à une forte augmentation du trafic |
| Soak (Endurance) | Charge modérée sur plusieurs heures | Fuites de mémoire, dégradation lente |
Vous n'avez pas besoin des cinq. Commencez par les tests de fumée et de charge normale. Ajoutez les tests de stress et de pointe une fois que vous connaissez vos chiffres normaux. Pour un aperçu plus large des approches et des métriques qui les sous-tendent, les fondamentaux des tests de performance sont valables pour tous les outils, pas seulement k6.
Lecture des résultats k6
Lorsqu'une exécution se termine, k6 affiche un résumé dans le terminal. Les lignes les plus importantes :
- http_req_duration : temps total de requête, affiché en moyenne, min, max, médiane, p90 et p95. Les centiles p95 et p99 vous indiquent ce que vos utilisateurs les plus lents expérimentent réellement. Les moyennes cachent la douleur ; les centiles la révèlent.
- http_req_failed : la part des requêtes qui ont échoué. Observez comment cela évolue à mesure que les VU augmentent.
- http_reqs : total des requêtes et requêtes par seconde. C'est votre débit.
- iterations : combien de passages complets ont été effectués, et le taux.
- vus et vus_max : utilisateurs virtuels actifs et maximum.
- checks : le taux de réussite de vos assertions
check().
Lisez les centiles, pas les moyennes. Un temps de réponse moyen de 200ms semble correct jusqu'à ce que vous voyiez un p99 de 4 secondes, ce qui signifie qu'un utilisateur sur cent attend quatre secondes. Cette « queue » est l'endroit où les utilisateurs abandonnent.
Pour aller au-delà d'une simple lecture visuelle du terminal, k6 peut diffuser les résultats vers des sorties externes. Il écrit des fichiers JSON ou CSV, et s'intègre aux tableaux de bord Grafana et à Prometheus pour une analyse visuelle en direct pendant une exécution. Ce jumelage, k6 et Grafana, explique pourquoi vous verrez souvent l'outil appelé « grafana k6 ». Pour un test ponctuel, le résumé du terminal est suffisant ; pour une surveillance continue, envoyez les métriques là où vous pouvez les visualiser.
Où k6 s'intègre, et où Apidog s'intègre
k6 est un moteur de charge. Il répond à la question « comment mon système se comporte-t-il sous un trafic soutenu ? ». Il ne vérifie pas si votre API renvoie les bonnes données, respecte son contrat ou gère correctement l'authentification sur chaque point de terminaison. Ce sont des questions de tests fonctionnels et contractuels, et elles nécessitent un outil différent.
C'est la distinction qu'il faut garder claire. Vous voulez les deux types de tests dans votre pipeline, et ils ne sont pas en concurrence :
| Préoccupation | Mieux géré par | Ce à quoi cela répond |
|---|---|---|
| Charge lourde soutenue, centiles à l'échelle | k6 | Reste-t-il rapide sous le trafic |
| Correction fonctionnelle, contrat, authentification | Apidog | Renvoie-t-il la bonne chose |
| Régression en CI à chaque commit | Apidog (apidog run) |
Ce changement a-t-il cassé un point de terminaison |
| Budgets de performance en CI | Seuils k6 | La latence ou les erreurs ont-elles dépassé une limite |
Apidog gère l'aspect de la justesse. Vous concevez ou importez votre API, construisez des scénarios de test avec des assertions visuelles, et les exécutez en CI avec apidog run, de la même manière que vous exécuteriez un script k6. Le guide CLI d'Apidog explique comment intégrer ces tests fonctionnels dans un pipeline. Apidog inclut également des fonctionnalités de test de performance plus légères pour des vérifications rapides, couvertes dans le guide des tests de performance API dans Apidog, mais ce n'est pas un générateur de charge de la classe k6 et il ne cherche pas à l'être.
Un workflow pratique ressemble à ceci. À chaque commit, Apidog exécute vos tests fonctionnels et contractuels pour confirmer que l'API fait toujours ce qu'elle doit. Selon un calendrier ou avant une publication, k6 exécute un profil de charge contre un environnement de staging pour confirmer que l'API reste rapide sous le trafic. Une porte de justesse et une porte de performance, chacune avec l'outil conçu pour elle.
Si vous comparez les moteurs avant de vous engager, k6 se situe à côté de JMeter, Gatling et Locust. Le récapitulatif des outils de test de charge et cette comparaison des alternatives à Locust exposent les compromis si le langage de script ou l'échelle influencent votre choix.
Questions fréquemment posées
Est-ce que k6 est gratuit ?
Oui. k6 est open source sous licence AGPL, et le binaire est gratuit à exécuter localement sans limite sur les utilisateurs virtuels au-delà des capacités de votre propre matériel. Grafana propose également k6 Cloud, un service payant pour exécuter de grands tests distribués et stocker les résultats, mais vous n'êtes jamais obligé de l'utiliser. L'outil de base couvre la plupart des équipes. Si vous voulez d'abord examiner d'autres options gratuites, l'aperçu des outils de test de charge répertorie ce que chacun offre.
Ai-je besoin de connaître JavaScript pour utiliser k6 ?
Vous avez besoin de connaissances JavaScript de base, pas d'une expertise approfondie. La plupart des scripts k6 sont une fonction par défaut, quelques appels http.get ou http.post, quelques vérifications et un objet options. Si vous pouvez lire les exemples de ce guide, vous pouvez écrire un test fonctionnel. Il n'y a pas d'étape de compilation ni de framework à apprendre, juste l'API k6.
Quelle est la différence entre k6 et Apidog pour les tests de performance ?
k6 est un générateur de charge dédié conçu pour générer un trafic lourd et soutenu et rapporter les centiles à grande échelle. Apidog est une plateforme API axée sur la conception, les tests fonctionnels et les tests de contrat, avec des fonctionnalités de test de performance plus légères pour des vérifications rapides. Utilisez k6 lorsque vous avez besoin d'une charge réelle et de budgets de performance en CI. Utilisez Apidog pour la justesse, la validation de contrat et l'exécution de tests fonctionnels à chaque commit. Ils résolvent des problèmes différents et fonctionnent bien ensemble.
Puis-je exécuter k6 en CI/CD ?
Oui, et c'est une configuration courante. k6 se termine avec un code non nul lorsqu'un seuil échoue, de sorte que tout système CI peut faire échouer la construction en cas de régression de performance. Exécutez k6 run script.js comme étape de pipeline, pointez-le vers un environnement de staging, et définissez des seuils pour la latence p95 et le taux d'erreur. Associez-le à des tests fonctionnels d'apidog run afin que chaque commit bénéficie à la fois d'une vérification de justesse et d'une vérification de charge.
Conclusion
k6 vous offre un moyen propre et scriptable de soumettre votre API à une charge réelle et de mesurer ce qui se passe. Installez le binaire, écrivez un court fichier JavaScript, définissez les VU et les étapes, ajoutez des seuils et lisez les centiles. C'est tout le processus. Gardez les tests de charge séparés des tests fonctionnels, car chacun répond à une question différente, et exécutez les deux en CI pour que rien ne passe inaperçu.
Pour le côté justesse de cette séparation, Apidog vous permet de concevoir, tester, simuler et documenter votre API en un seul endroit, puis d'exécuter des tests fonctionnels en CI avec apidog run. Téléchargez Apidog pour associer la confiance au niveau du contrat à vos exécutions de charge k6.
bouton
