RousselTMLEARNING

DevOps

Écrire des scripts k6 : requêtes, vérifications, scénarios et exécuteurs

La structure d'un script k6 (init, setup, default, teardown), les requêtes HTTP, les checks, les groupes et tags, et la modélisation de la charge avec les scénarios et exécuteurs.

1. Anatomie d'un script #

Init, setup, default, teardown.

Premier script #

Cycle de vie d'un test k6
Seule la fonction par défaut est répétée par chaque utilisateur virtuel (VU).
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  vus: 10,            // utilisateurs virtuels simultanés
  duration: '30s',
};

export default function () {
  const res = http.get('http://localhost:8080/get');
  check(res, {
    'statut 200': (r) => r.status === 200,
    'moins de 300 ms': (r) => r.timings.duration < 300,
  });
  sleep(1);           // temps de réflexion de l'utilisateur
}
k6 run script.js
Bonne Pratique : Un check ne fait pas échouer le test : il compte les succès et les échecs. Pour faire échouer un test, utilisez les seuils (thresholds).

2. Requêtes réalistes #

Données, en-têtes, groupes.

Exemples #

import http from 'k6/http';
import { group } from 'k6';

export function setup() {        // exécuté une fois : par exemple, obtenir un jeton
  const res = http.post('http://api/login', JSON.stringify({ user: 'demo', pass: 'demo' }),
                        { headers: { 'Content-Type': 'application/json' } });
  return { token: res.json('token') };
}

export default function (data) {
  const params = { headers: { Authorization: `Bearer ${data.token}` }, tags: { name: 'commande' } };
  group('parcours achat', () => {
    http.get('http://api/produits');
    http.post('http://api/panier', JSON.stringify({ id: 42 }), params);
  });
}
Erreur Courante : Les URL avec identifiants (/produits/123) créent une série de métriques par URL. Donnez-leur un tag name commun ({ tags: { name: 'produit' } }) pour garder des résultats lisibles.

3. Scénarios et exécuteurs #

Modéliser la charge.

VU ou débit ? #

Les exécuteurs décident comment la charge est générée. Deux familles :

ExécuteurModèleUsage
constant-vus, ramping-vusFermé : N utilisateurs qui enchaînent les itérationsSimuler des sessions utilisateur
constant-arrival-rate, ramping-arrival-rateOuvert : N itérations par seconde, quoi qu'il arriveMesurer une API à débit donné
shared-iterations, per-vu-iterationsNombre fixe d'itérationsTraitements, tests fonctionnels
À savoir : Avec un modèle fermé, si le service ralentit, chaque VU fait moins de requêtes : la charge baisse et masque le problème. Un modèle ouvert (arrival rate) maintient le débit et révèle la saturation.

Plusieurs scénarios #

export const options = {
  scenarios: {
    navigation: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '2m', target: 50 },   // montée
        { duration: '5m', target: 50 },   // plateau
        { duration: '1m', target: 0 },    // descente
      ],
      exec: 'parcours',
    },
    api: {
      executor: 'constant-arrival-rate',
      rate: 200, timeUnit: '1s',          // 200 requêtes par seconde
      duration: '8m',
      preAllocatedVUs: 50, maxVUs: 300,
      exec: 'appelApi',
    },
  },
};
export function parcours() { /* ... */ }
export function appelApi() { /* ... */ }

Articles liés

Tests de charge avec Grafana k6 : pourquoi et quels types de tests

Pourquoi tester la performance avant la production, les types de tests (smoke, charge, stress, pic, endurance…

Seuils, métriques et résultats d'un test k6

Lire le résumé d'un test k6, comprendre les métriques intégrées (http_req_duration, http_req_failed, iteratio…

Observer un test k6 : Prometheus, Grafana et corrélation avec le système testé

Envoyer les résultats de k6 dans Prometheus (remote write) ou en OpenTelemetry, les visualiser dans Grafana e…

Pour aller plus loin