Tests de charge vs tests de contrainte : différences, métriques et exemples k6

  1. Accueil
  2. Blog
  3. Tests de logiciels

Tests de logiciels

Tests de charge vs tests de contrainte : Différences, métriques et exemples k6

Cela prouve que votre système gère le trafic que vous attendez. L’autre découvre où il se brise et comment il récupère. Apprenez quand exécuter chacun d’eux, à quels chiffres se fier et comment planifier un test qui donne de vraies réponses.

9 min de lecture
Tests de charge vs tests de contrainte : différences, métriques et exemples k6

À retenir

  • Les Tests de charge vérifient qu’un système atteint ses objectifs dans le cadre du trafic attendu.
  • Les tests de résistance dépassent les capacités pour trouver le point de rupture et étudier la récupération.
  • Les outils sont généralement les mêmes. Ce qui diffère, c’est l’objectif et le modèle de trafic.
  • Jugez les résultats avec des centiles tels que p95 et p99, car les moyennes peuvent cacher de graves problèmes.

Votre application fonctionne parfaitement avec dix utilisateurs. Que se passe-t-il le jour de la vente, avec dix mille ? Tests de charge vs tests de stress décrit deux manières différentes de répondre à cette question, et les mélanger conduit à des tests qui ne prouvent pas ce que vous pensez qu’ils font.

Ce guide explique ce que chacun montre, les types de tests associés et comment lire les résultats. Nous avons effectué le calcul du petit centile ci-dessous sur Python 3.13, avec des nombres simulés. Les scripts k6 sont des exemples illustratifs que nous n’avons pas exécutés, et les comptes d’utilisateurs et les cibles sont inventés, alors remplacez-les par les vôtres. Exécutez ces tests uniquement sur les systèmes que vous possédez ou que vous êtes autorisé à tester, car un trafic important peut ressembler à une attaque et provoquer de véritables pannes.

La réponse courte

Un test de charge demande : pouvons-nous gérer le trafic auquel nous nous attendons et atteindre nos objectifs en le faisant ? Un stress test pose la question suivante : combien pouvons-nous prendre avant d’échouer, comment échouons-nous et à quelle vitesse pouvons-nous nous rétablir ?

Pensez à un pont. Un test de charge fait circuler le nombre prévu de camions et confirme que tout va bien. Un test de résistance continue d’ajouter du poids pour connaître sa limite et savoir s’il donne un avertissement en premier. Heureusement, un logiciel coûte moins cher à briser qu’un pont.

Tests de charge et tests de contrainte côte à côte

Aspect Test de charge Tests de résistance
Question principale Atteignons-nous les objectifs à la charge prévue ? Où et comment fait-on une pause ?
Niveau de trafic Pic normal à attendu Au-delà du pic attendu
Modèle Accélérez, restez stable Continuer à augmenter jusqu’à l’échec
Échec Un test raté Le résultat attendu
Indicateurs clés Temps de réponse, débit, erreurs Point de rupture, mode de défaillance, temps de récupération
Calendrier typique Avant chaque sortie ou événement majeur Une fois que le système est stable sous charge
Résultat Réussir ou échouer contre les cibles Une limite de capacité et une liste de points faibles

Qu’est-ce que le test de charge ?

Les tests de charge simulent le trafic réaliste auquel vous vous attendez et mesurent le comportement du système. Il a besoin d’un objectif de test, par exemple : « avec 500 utilisateurs simultanés, 95 % des demandes de paiement se terminent dans un délai de 800 ms, avec moins de 1 % d’erreurs. »

Voici à quoi cela pourrait ressembler en tant que script k6. Les tests k6 sont écrits en JavaScript et thresholds transforment vos objectifs en résultat de réussite ou d’échec :

import http from "k6/http";
import { sleep } from "k6";

export const options = {
  stages: [
    { duration: "5m", target: 500 },   // ramp up
    { duration: "20m", target: 500 },  // hold at expected peak
    { duration: "2m", target: 0 },     // ramp down
  ],
  thresholds: {
    http_req_duration: ["p(95)<800"],
    http_req_failed: ["rate<0.01"],
  },
};

export default function () {
  http.get("https://staging.example.com/products");
  sleep(1);   // think time, as real users pause
}

Le sleep compte. Sans temps de réflexion, chaque utilisateur virtuel martèle continuellement le serveur, générant bien plus de trafic que ne le ferait le même nombre de personnes réelles.

Qu’est-ce que les tests de résistance ?

Les tests de résistance vont délibérément au-delà des niveaux attendus. Vous n’essayez pas de réussir. Vous voulez des réponses à des questions telles que :

  • À quel niveau les performances commencent-elles à s’effondrer ?
  • Quel composant tombe en panne en premier : la base de données, les serveurs d’applications ou un appel tiers ?
  • Est-ce qu’il échoue normalement avec des erreurs claires, ou est-ce qu’il plante et perd des données ?
  • Est-ce qu’il se rétablit tout seul lorsque le trafic baisse ?
export const options = {
  stages: [
    { duration: "5m", target: 500 },    // expected peak
    { duration: "5m", target: 1000 },   // beyond it
    { duration: "5m", target: 2000 },   // further
    { duration: "5m", target: 4000 },   // likely to break
    { duration: "10m", target: 0 },     // recovery: does it come back?
  ],
};

Cette dernière étape de récupération est souvent oubliée, et elle est peut-être la plus précieuse. Un système qui gère bien les pannes mais ne se rétablit jamais sans un redémarrage manuel signifie toujours une panne que quelqu’un doit réparer au milieu de la nuit. Idéalement, sous une charge extrême, un système devrait abandonner le travail de manière contrôlée, en renvoyant des 503 réponses claires au lieu d’expirer.

Spike, trempage et autres types

Les tests de charge et de contrainte appartiennent à une famille plus large de tests de performances :

Tapez Modèle Ce qu’il trouve
Fumée (performance) Quelques utilisateurs, brièvement Si le script et le système fonctionnent du tout
Charger Pic attendu, tenu Si les objectifs sont atteints
Stress Dépassement de capacité Limites et modes de défaillance
Pointe Un saut soudain, puis une chute Comportement de mise à l’échelle automatique et de file d’attente
Trempage (endurance) Charge normale pendant des heures Fuites de mémoire, connexions épuisées
Capacité Augmentation progressive La charge maximale dans vos objectifs

Les tests d’immersion détectent des problèmes que les tests courts ne détectent jamais. Une petite fuite de mémoire peut sembler inoffensive pendant vingt minutes et n’interrompre le service qu’au bout de deux jours. Les tests Spike conviennent à des événements tels que les ventes flash, où le trafic ne se développe pas progressivement.

Des indicateurs qui comptent

Métrique Signification Surveillez
Temps de réponse (percentiles) Combien de temps prennent les demandes p95 et p99 en hausse
Débit Requêtes traitées par seconde Aplatissement à mesure que le nombre d’utilisateurs augmente
Taux d’erreur Pourcentage de demandes ayant échoué Toute hausse soudaine
Processeur et mémoire Utilisation des ressources du serveur Saturation, ou croissance régulière
Base de données Requêtes lentes, utilisation du pool de connexions Épuisement de la piscine, le verrou attend
Profondeur de la file d’attente Travaux en attente de traitement Une croissance qui ne s’épuise jamais

Pourquoi les moyennes sont trompeuses

Les moyennes cachent la lenteur des requêtes dont se plaignent les vraies personnes. Pour le montrer, nous avons généré 100 temps de réponse simulés, dont 95 étaient rapides (80 à 200 ms) et 5 très lents (2,5 à 4 secondes), puis avons calculé les statistiques communes :

import math, random, statistics

random.seed(3)
times = [random.randint(80, 200) for _ in range(95)] \
      + [random.randint(2500, 4000) for _ in range(5)]

def pct(values, p):
    values = sorted(values)
    return values[math.ceil(p / 100 * len(values)) - 1]

print("avg", round(statistics.mean(times)), "p50", pct(times, 50),
      "p95", pct(times, 95), "p99", pct(times, 99), "max", max(times))

# avg 302 p50 150 p95 199 p99 3740 max 3896

Regardez attentivement ces chiffres. La moyenne de 302 ms ne décrit personne. Les requêtes typiques prenaient environ 150 ms, tandis que les requêtes lentes prenaient plus de 3 secondes. Même p95 semble sain à 199 ms, et seul p99 révèle le problème. Un chiffre comme p95 signifie que 95 % des requêtes ont été aussi rapides ou plus rapides.

Et un pour cent des demandes n’est pas un événement rare. Si une page effectue 50 requêtes, un p99 lent affecte une grande partie des pages vues. Fixez des objectifs sur les percentiles qui comptent pour vous et examinez-en plusieurs ensemble.

Conseil : Recherchez le « genou » dans vos graphiques. À mesure que la charge augmente, les temps de réponse restent stables pendant un certain temps, puis augmentent soudainement, tandis que le débit cesse de croître. Ce point dépend de votre capacité pratique, et il arrive souvent bien avant que quoi que ce soit ne plante réellement.

Outils

Outil Script Connu pour
k6 Javascript Conviviaux pour les développeurs, les seuils conviennent à CI
JMètre Interface graphique et XML Mature, prend en charge de nombreux protocoles
Gatling Scala, Java, Kotlin et autres Basé sur du code, efficace
Criquet Python Comportement utilisateur simple, basé sur Python

N’importe lequel d’entre eux peut exécuter à la fois des tests de charge et de stress. Choisissez celui qui correspond aux compétences de votre équipe, plutôt que de courir après une liste de fonctionnalités. Pour en utiliser un dans votre pipeline, consultez qu’est-ce que CI/CD.

Comment planifier un test

  1. Fixez-vous des objectifs. Utilisez de véritables analyses pour déterminer votre pic de trafic et définir des cibles.
  2. Choisissez des parcours. Modélisez un comportement réaliste des utilisateurs, tel que la navigation, la recherche et le paiement, dans des proportions réalistes. Frapper uniquement la page d’accueil ne prouve pas grand-chose.
  3. Utilisez un environnement réaliste. Un petit serveur intermédiaire ne peut pas prédire la production. Notez toutes les différences.
  4. Préparez les données. Utilisez des volumes réalistes, car une requête rapide sur 100 lignes peut en explorer 10 millions.
  5. Avertissez les gens. Informez votre équipe opérationnelle et tout tiers, et ne testez pas de charge un fournisseur de paiement par accident. Moquez-vous des services externes le cas échéant.
  6. Commencez petit. Exécutez d’abord un petit test de fumée pour confirmer que votre script fonctionne.
  7. Surveillez tout. Sans les métriques du serveur, vous verrez que il a ralenti, mais pas pourquoi.
  8. Répétez. Exécutez-le à nouveau après chaque correctif et conservez une base de référence à laquelle comparer.

Lire les résultats

Symptôme Cause possible
Réponses lentes, mais processeur faible En attente d’une base de données, d’un verrou ou d’un service externe
Le processeur de la base de données est élevé Index manquants ou requêtes inefficaces
Erreurs de connexion soudaines Pool de connexions ou limite de fichiers atteinte
La mémoire grimpe régulièrement Une fuite ou un cache illimité
Le processeur du générateur de charge est élevé L’outil de test est le goulot d’étranglement, pas votre système

Les bases de données constituent un goulot d’étranglement courant. Si les requêtes constituent le problème, lisez notre guide sur l’optimisation des requêtes SQL. Cette dernière ligne du tableau est un piège important : vérifiez toujours également l’état de la machine générant la charge.

Erreurs courantes

  • Confondre les utilisateurs avec les requêtes. Indiquez clairement si une cible signifie des utilisateurs simultanés ou des requêtes par seconde.
  • Laisser de côté le temps de réflexion. Cela gonfle le trafic et donne des résultats trompeurs.
  • Tests trop tardifs. Une semaine avant le lancement ne laisse pas le temps de résoudre les problèmes d’architecture.
  • Utilisation d’un seul point de terminaison. Le trafic réel mélange les lectures, les écritures et les recherches.
  • La mise en cache cache tout. Des requêtes répétées identiques peuvent uniquement tester votre cache, alors faites varier les données.
  • Test une fois. Les performances changent à chaque version, alors exécutez des tests régulièrement.

Pour conclure

Exécutez des tests de charge pour confirmer que vous pouvez gérer le trafic que vous attendez, et des tests de résistance pour savoir ce qui se passe lorsque vous ne le pouvez pas. Commencez petit : choisissez votre parcours utilisateur le plus important, définissez un objectif clair et exécutez un court test par rapport à la mise en scène avec la surveillance activée. Cette première exécution vous apprend généralement quelque chose et vous pouvez construire à partir de là.

Questions fréquentes

Quelle est la principale différence entre les tests de charge et de stress ?

Les tests de charge vérifient le comportement du trafic attendu par rapport aux objectifs définis. Les tests de résistance vont au-delà de la capacité à trouver le point de rupture et la manière dont le système se rétablit.

Dois-je d’abord exécuter des tests de charge ou des tests de résistance ?

Testez d’abord la charge. Une fois que le système atteint ses objectifs dans le cadre du trafic prévu, effectuez des tests de résistance pour explorer ses limites. Les résultats de stress signifient peu sur un système instable.

Quelle est la différence entre un test de stress et un test de pointe ?

Un test de résistance augmente généralement la charge étape par étape jusqu’à la défaillance. Un test de pointe passe soudainement à un niveau élevé, pour voir comment le système fait face à un changement brusque.

Quel est le temps de réponse p95 ?

Cela signifie que 95 % des demandes sont terminées à ce moment-là ou en dessous. Il décrit mieux l’expérience de la plupart des utilisateurs que la moyenne.

Puis-je exécuter des tests de charge en production ?

Vous pouvez le faire, mais avec précaution, avec la permission, la surveillance et un moyen de vous arrêter rapidement. La plupart des équipes commencent par un environnement de simulation de type production afin de réduire les risques pour les utilisateurs réels.

Continuez à apprendre

Travailler avec Stack Quora

Besoin d’aide pour les tests, WordPress ou le référencement ?

Nous aidons les équipes à proposer de meilleurs logiciels et à développer leurs sites. Dites-nous sur quoi vous travaillez et nous vous proposerons une prochaine étape claire.

Continuez à lire

Plus de guides sur tests, IA et développement moderne

Vous avez apprécié cet article ? Choisissez un sujet et accédez directement à nos nouveaux didacticiels.

Intelligence artificielle

Les hallucinations de l'IA expliquées : pourquoi les modèles de langage inventent les choses et comment les réduire

Les hallucinations de l'IA ont expliqué : ce qu'elles sont, pourquoi les modèles de langage les produisent, les types courants, comment les réduire …

Lire l'article →
DevOps

Variables d'environnement expliquées : fichiers .env, secrets et configuration correctement effectués

Variables d'environnement expliquées avec des exemples Python que nous avons exécutés : lecture et définition, pourquoi chaque valeur est une chaîne…

Lire l'article →
Développement logiciel

Limitation du débit de l'API expliquée : algorithmes, en-têtes et gestion des erreurs 429

Limitation du débit de l'API expliquée avec une simulation que nous avons exécutée : compartiment de jetons, fenêtre fixe, fenêtre glissante, 429 ré…

Lire l'article →
Automatisation des tests

Se moquer en Python : unittest.mock, patch et les erreurs qui font mentir les tests

Moquerie en Python avec unittest.mock, testée : Mock et return_value, side_effect, correctifs où un nom est utilisé, spec et autospec, dates moqueus…

Lire l'article →
Tests logiciels

Couverture du code expliquée : couverture des lignes par rapport aux branches et ce que signifie réellement 100 %

Couverture du code expliquée avec une véritable exécution de cover.py : couverture des lignes, des branches et des conditions, lecture d'un rapport,…

Lire l'article →
Bases de données et SQL

DELETE vs TRUNCATE vs DROP dans SQL : différences, restauration et quand les utiliser

DELETE vs TRUNCATE vs DROP expliqué avec SQL testé : ce que chacun supprime, restauration, déclencheurs, réinitialisation d'identité, vitesse et en …

Lire l'article →
Bases de données et SQL

Vues SQL expliquées : créez, utilisez et évitez les pièges, avec des exemples

Vues SQL expliquées avec les requêtes que nous avons exécutées : création d'une vue, résultats en direct, masquage des colonnes, performances, vues …

Lire l'article →
Développement logiciel

Interface TypeScript vs Type : différences réelles, testées avec le compilateur

Interface TypeScript vs type, vérifiée avec le vrai compilateur : ce que les deux peuvent faire, ce qu'un seul peut faire, la fusion des déclaration…

Lire l'article →
Développement logiciel

Python *args et **kwargs expliqués : fonctions flexibles avec des exemples clairs

Python *args et **kwargs expliqués avec le code que nous avons exécuté : emballage et déballage, ordre des paramètres, arguments de mot-clé uniqueme…

Lire l'article →
Développement logiciel

Fonctions Python Lambda : syntaxe, utilisations réelles et quand ne pas les utiliser

Fonctions Python lambda expliquées avec le code que nous avons exécuté : syntaxe, tri avec clé, carte et filtre, fermetures, piège de liaison tardiv…

Lire l'article →
Intelligence artificielle

Que sont les agents IA ? Comment ils fonctionnent, avec une simple boucle d'agent que vous pouvez exécuter

Que sont les agents IA ? Un guide simple sur la boucle d'agent, les outils, la mémoire et les garde-fous, avec une petite boucle Python que nous avo…

Lire l'article →
DevOps

Surveillance vs observabilité : la vraie différence, avec les journaux, les métriques et les traces

Surveillance et observabilité expliquées : échecs connus et inconnus, journaux, métriques et traces, présentation pas à pas des incidents de paiemen…

Lire l'article →
DevOps

Volumes Docker vs montages Bind : conserver les données du conteneur de la bonne manière

Volumes Docker et montages de liaison expliqués : pourquoi les données du conteneur disparaissent, volumes nommés, montages de liaison, tmpfs, exemp…

Lire l'article →
Automatisation des tests

TDD vs BDD : principales différences, une fonctionnalité conçue dans les deux sens et quand les utiliser

TDD vs BDD expliqué avec une fonctionnalité de remise construite dans les deux sens : refactor rouge-vert avec le code que nous avons exécuté, scéna…

Lire l'article →
Tests logiciels

Tests d'acceptation utilisateur (UAT) : processus, liste de contrôle et exemples réels

Les tests d'acceptation des utilisateurs sont expliqués : qui les exécute, en quoi ils diffèrent du contrôle qualité, un processus en sept étapes, u…

Lire l'article →
Bases de données et SQL

Explication des valeurs SQL NULL : IS NULL, COALESCE, NULLIF et les pièges à éviter

Les valeurs SQL NULL expliquées avec les requêtes que nous avons exécutées : logique à trois valeurs, IS NULL, COALESCE, NULLIF, comment les agrégat…

Lire l'article →
Bases de données et SQL

Instruction SQL CASE WHEN : syntaxe, exemples réels et erreurs courantes

SQL CASE WHEN expliqué avec les requêtes que nous avons exécutées : formulaires simples et recherchés, ordre des conditions, pivots avec SUM, astuce…

Lire l'article →
Développement logiciel

Qu'est-ce que JWT ? Les jetons Web JSON expliqués avec un exemple fonctionnel

Qu’est-ce que JWT ? JSON Web Tokens expliqué : les trois parties, un jeton construit et falsifié dans le code que nous avons exécuté, JWT vs session…

Lire l'article →
Développement logiciel

Boucle d'événements JavaScript expliquée : pile d'appels, microtâches et minuteries avec des exemples

La boucle d'événements JavaScript expliquée avec le code que nous avons exécuté : pile d'appels, files d'attente de tâches et de microtâches, pourqu…

Lire l'article →
Développement logiciel

Générateurs Python et rendement expliqués : économisez de la mémoire avec des exemples réels

Les générateurs Python et le rendement expliqués avec le code que nous avons exécuté : comment ils s'arrêtent et reprennent, les économies de mémoir…

Lire l'article →
Intelligence artificielle

Que sont les intégrations ? Vecteurs et similarité cosinus expliqués simplement

Que sont les intégrations ? Un guide en langage simple sur les vecteurs, la similarité cosinus et la recherche sémantique, avec un petit exemple que…

Lire l'article →
DevOps

Déploiement Bleu-Vert vs Canary : différences, compromis et comment choisir

Explication du déploiement bleu-vert ou canari : comment chacun fonctionne, coût, risque et restauration, regroupement d'utilisateurs stable que nou…

Lire l'article →
Automatisation des tests

Tests instables : quelles sont leurs causes et comment les corriger définitivement

Des tests irréguliers expliqués avec des démos que nous avons exécutées : les principales causes, comment en confirmer et en diagnostiquer une, les …

Lire l'article →
Tests logiciels

Tests de charge vs tests de contrainte : différences, métriques et exemples k6

Explication des tests de charge et des tests de stress : ce que chacun prouve, les tests de pointe et de trempage, les métriques qui comptent, pourq…

Lire l'article →
Tests logiciels

Scénario de test et scénario de test : principales différences, exemples et quand les utiliser

Scénario de test et scénario de test expliqués : des définitions claires, un tableau côte à côte, une fonctionnalité de réinitialisation de mot de p…

Lire l'article →
Bases de données et SQL

Optimisation des requêtes SQL : lire les plans d'exécution et corriger les requêtes lentes, avec des délais

Optimisation des requêtes SQL testée sur un million de lignes : lire les plans d'exécution, ajouter les bons index, corriger les filtres non Sargabl…

Lire l'article →
Bases de données et SQL

SQL UNION vs UNION ALL : différences, exemples et performances testées

SQL UNION vs UNION ALL expliqué avec les requêtes que nous avons exécutées : des doublons, les règles suivent toutes les deux, un véritable bug de d…

Lire l'article →
Développement logiciel

Tutoriel API JavaScript Fetch : GET, POST, gestion des erreurs et délais d'attente

Un didacticiel de l'API JavaScript Fetch testé sur un serveur local : GET et POST, pourquoi 404 ne lance pas, un assistant réutilisable, des chaînes…

Lire l'article →
Développement logiciel

Gestion des fichiers Python : lecture, écriture, CSV, JSON et pathlib avec exemples

Gestion des fichiers Python expliquée avec le code que nous avons exécuté : modes ouverts, avec lecture de fichiers volumineux, CSV, JSON, pathlib, …

Lire l'article →
Développement logiciel

Git merge vs rebase : différences, exemples et quand utiliser chacun

Git merge vs rebase expliqué avec de vraies sorties de log, un tableau comparatif, la règle d'or du rebase et un flux de travail sûr pour les équipes.

Lire l'article →
Développement logiciel

List comprehension Python : syntaxe, exemples et cas à éviter

La list comprehension Python expliquée : syntaxe, filtres, if-else, boucles imbriquées, temps mesurés et cas où une boucle for classique est préféra…

Lire l'article →
Bases de données et SQL

Jointures SQL expliquées avec exemples (Inner, Left, Right, Full)

Comprenez les jointures SQL pas à pas avec des tables et requêtes d'exemple : INNER, LEFT, RIGHT, FULL, CROSS et SELF, plus erreurs courantes et con…

Lire l'article →