1. Anatomie d'un script #
Init, setup, default, teardown.
Premier script #
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.jsBonne 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 tagnamecommun ({ 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écuteur | Modèle | Usage |
|---|---|---|
constant-vus, ramping-vus | Fermé : N utilisateurs qui enchaînent les itérations | Simuler des sessions utilisateur |
constant-arrival-rate, ramping-arrival-rate | Ouvert : N itérations par seconde, quoi qu'il arrive | Mesurer une API à débit donné |
shared-iterations, per-vu-iterations | Nombre fixe d'itérations | Traitements, 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() { /* ... */ }