Outils de test de charge WebSocket : six options
7 min de lecture
Parmi les outils de test de charge WebSocket, k6, Artillery, Gatling et Tsung gèrent le protocole nativement, tandis que JMeter a besoin du plugin WebSocket Samplers et Locust de code client que vous écrivez ou de son utilisateur Socket.IO expérimental. Choisissez selon le langage de votre équipe, puis selon la rigueur avec laquelle vous devez vérifier les messages que le serveur renvoie.
Pour cet article, nous n’avons pas lancé ces outils contre un serveur WebSocket. Les informations viennent de la documentation et du dépôt de chaque projet, vérifiées le 9 octobre 2026, et les conseils « Choisissez plutôt » sont notre jugement.
| Outil | Prise en charge de WebSocket | Tests écrits en | Vérifier ce que le serveur envoie |
|---|---|---|---|
| k6 | Intégrée : k6/websockets, ancien k6/ws | JavaScript | Gestionnaires d’événements dans votre script |
| Artillery | Moteurs intégrés ws et socketio | YAML, plus des fonctions JavaScript | Réponses et accusés de réception Socket.IO |
| Gatling | Fait partie du SDK HTTP | Java, Kotlin, Scala, JavaScript | Checks qui attendent un message précis |
| Apache JMeter | Plugin WebSocket Samplers | Plans de test construits dans l’interface graphique | Samplers request-response et de lecture |
| Locust | Votre propre client, ou le SocketIOUser expérimental | Python | Ce que votre code remonte |
| Tsung | Type de session intégré ts_websocket | XML | ack attend une réponse du serveur |
En quoi la charge WebSocket diffère-t-elle de la charge HTTP ?
Un utilisateur WebSocket ouvre une connexion et la garde pendant toute la session, et le serveur peut envoyer des messages quand il le veut. Un test a donc deux leviers, les connexions ouvertes et les messages par seconde, et chacun sollicite le serveur à sa façon.
Le guide WebSocket de k6 décrit un trafic full-duplex sur une seule connexion TCP et explique qu’un utilisateur virtuel y exécute une boucle d’événements tant que le socket reste ouvert, sans plus boucler sur la fonction principale. La référence WebSocket de Gatling ajoute que le trafic circule dans les deux sens, si bien que le modèle requête-réponse de HTTP ne convient plus.
Prévoyez trois formes de test. Beaucoup de connexions inactives montrent combien de sockets vos serveurs peuvent tenir. Un groupe plus restreint de clients bavards teste le traitement des messages. Une diffusion, où un message part vers tous les abonnés, teste le chemin du push.
Que faut-il mesurer dans un test de charge WebSocket ?
Mesurez le temps de connexion, la latence des messages et les connexions perdues, ainsi que le nombre de connexions qui restent ouvertes. Ce sont ces valeurs que ressentent les utilisateurs d’une application temps réel.
Les métriques intégrées de k6 comprennent ws_connecting, ws_ping, ws_session_duration, ws_sessions et des compteurs de messages. Aucune ne chronomètre un message applicatif : le délai entre le message d’un client et la réponse du serveur demande une métrique Trend personnalisée. Le moteur ws d’Artillery remonte le nombre et le débit des messages, et son moteur Socket.IO ajoute socketio.response_time, de l’émission d’un message à la réception de la réponse.
Pour les connexions perdues, comptez les événements close et error que votre script n’a pas provoqués, et comparez les sessions ouvertes à celles encore actives à la fin de chaque palier.
Quand k6 est-il le bon outil WebSocket ?
Quand votre équipe écrit du JavaScript et que chaque utilisateur virtuel doit tenir plusieurs sockets à la fois. k6 intègre WebSocket d’origine, sans extension à installer.
Le module k6/websockets suit l’API WebSocket du navigateur et utilise une boucle d’événements globale, qui permet à un utilisateur virtuel de garder plusieurs connexions ouvertes. L’ancien module k6/ws reste documenté, mais k6 recommande k6/websockets pour les nouveaux tests, et k6/experimental/websockets est déprécié.
import { WebSocket } from 'k6/websockets';
export default function () {
const ws = new WebSocket('wss://example.com/ws');
ws.onopen = () => ws.send('hello');
ws.onmessage = (e) => {
console.log(e.data);
ws.close();
};
}
Les thresholds fonctionnent aussi sur les métriques personnalisées : un objectif de latence manqué donne donc à la CI un code de sortie non nul. Choisissez plutôt Artillery quand votre serveur parle Socket.IO et que vous voulez vérifier émissions et accusés de réception sans écrire de code client. Notre comparatif k6 vs Artillery couvre les autres différences.
Quand Artillery a-t-il du sens ?
Quand vous voulez des scénarios YAML courts, ou quand votre serveur utilise Socket.IO. Les deux moteurs sont fournis avec Artillery.
Un scénario sur le moteur WebSocket se compose de cinq actions : connect, send, think, loop et function. Le moteur Socket.IO va plus loin : un emit peut déclarer la réponse attendue, valider un accusé de réception par une correspondance JSONPath et partager un scénario avec des requêtes HTTP, ce qui convient aux applications qui se connectent en HTTP avant d’ouvrir un socket.
Choisissez plutôt k6 ou Gatling quand un test doit vérifier ce qu’un serveur WebSocket brut renvoie, car la documentation du moteur ws ne décrit aucune étape qui attende ou compare une réponse.
À qui s’adresse Gatling pour les WebSockets ?
Aux équipes sur la JVM, ou sur le SDK JavaScript de Gatling, qui veulent écrire les vérifications de messages dans le scénario. La prise en charge de WebSocket fait partie du SDK HTTP de Gatling, si bien que les étapes HTTP et WebSocket partagent une même simulation.
La référence couvre connect, sendText, sendBytes et close, ainsi que des checks qui bloquent jusqu’à l’arrivée du message attendu ou l’expiration d’un délai. Les réglages du protocole permettent de reconnecter un socket fermé par le serveur, de répondre automatiquement à certains messages texte comme un ping et de garder en mémoire tampon les messages qu’aucun check n’a reconnus. Le dépôt range WebSocket dans la Community Edition sous Apache 2.0, sans limite.
Choisissez plutôt k6 si vous préférez traiter les messages poussés dans des gestionnaires d’événements que dans des checks bloquants.
JMeter peut-il tester la charge des WebSockets ?
Oui, avec un plugin. JMeter n’a pas de sampler WebSocket, et l’extension habituelle est WebSocket Samplers de Peter Doornbosch.
La référence des composants de JMeter ne mentionne jamais WebSocket. Le dépôt du plugin décrit six samplers : ouverture de connexion, request-response, ping-pong, lecture simple, écriture simple et fermeture. Ils tournent sur le thread du groupe de threads, gèrent wss et les trames binaires, et peuvent filtrer les trames sans intérêt pour le test. On l’installe via le Plugins Manager ou en copiant son jar dans lib/ext, et la version 1.3.2 a été taguée en janvier 2026 (vérifié le 9 octobre 2026).
Choisissez un autre outil si vous préférez ne pas maintenir un plugin tiers sur chaque générateur de charge.
Et Locust et Tsung ?
Locust n’atteint les WebSockets bruts que par du code client que vous ajoutez, et Tsung les prend en charge dans sa configuration XML mais publie rarement de nouvelles versions. Les deux fonctionnent, au prix de plus d’efforts.
Selon la documentation de Locust, l’outil ne gère d’origine que HTTP et HTTPS ; les autres protocoles s’ajoutent en enveloppant une bibliothèque cliente et en déclenchant un événement request après chaque appel. La bibliothèque doit pouvoir être patchée par gevent, sinon elle bloque tout le processus. Pour Socket.IO, il existe un SocketIOUser expérimental. Choisissez Locust si votre équipe écrit du Python et accepte de maintenir ce code client.
Tsung est un projet Erlang qui se présente comme un outil de test de charge distribué et multi-protocole. Sa documentation des sessions définit pour WebSocket les requêtes connect, message et close, avec un attribut ack pour attendre une réponse. Sa dernière version taguée, la 1.8.0, date de mars 2023.
Où se situe un service hébergé comme LoadFocus ?
Tenir beaucoup de sockets ouverts depuis vos propres machines demande du travail, et un service hébergé prend en charge la génération de charge. Il convient surtout quand vos tests sont déjà des scripts k6.
LoadFocus, l’éditeur de ce site, exécute des scripts k6 depuis 25 régions cloud, et sa page k6 cite les connexions WebSocket parmi les fonctionnalités k6 prises en charge. Il propose aussi un modèle de test WebSocket avec montée et descente en charge. Nous n’avons pas vérifié s’il exécute des plugins JMeter comme WebSocket Samplers, nous n’affirmons donc rien à ce sujet.
Comment choisir entre eux ?
Partez du langage de votre équipe, puis demandez-vous si vous testez des WebSockets bruts ou Socket.IO et avec quelle rigueur vous devez vérifier les messages poussés. Il reste en général un ou deux candidats.
Écrivez le même test court de connexion, d’envoi et de réception dans les deux, puis comparez le temps de connexion et la latence des messages à faible charge. Notre guide Comment faire un test de charge détaille les étapes, et le panorama des outils de test de charge open source compare ces projets au-delà des WebSockets.
FAQ
Par quel outil de test de charge WebSocket commencer ? Si votre équipe écrit du JavaScript, commencez par k6, qui intègre WebSocket. Pour les applications Socket.IO, le moteur d’Artillery demande le moins de code, et les équipes JVM seront à l’aise avec Gatling.
JMeter peut-il tester les WebSockets sans plugin ?
Sa référence des composants ne cite aucun sampler WebSocket : la voie pratique est donc le plugin WebSocket Samplers, installé via le Plugins Manager ou comme jar dans lib/ext.
Faut-il utiliser k6/ws ou k6/websockets ?
Prenez k6/websockets pour les nouveaux tests, comme le recommande la documentation de k6. L’ancien module k6/ws reste documenté pour les scripts existants.
À lire aussi
- Outils de test de charge open source : six options
- Test de charge d’une API GraphQL : guide pratique
- Outils de benchmark HTTP : wrk, hey, oha, ab et autres
- Test de charge gRPC : outils, mise en place et mesures
- Test de charge Artillery : l’outil Node.js passé en revue
- Test de charge Tsung : l’outil Erlang passé en revue
Les affirmations techniques de cet article n'ont pas été relues de façon indépendante.