QA Learning / k6

Módulo 2: Anatomia de um script

As 4 peças de todo teste de carga, num roteiro de usuário que faz login, navega e compra.

As 4 peças

  • options: quanta carga e por quanto tempo (VUs, duração, thresholds).
  • export default function: o roteiro de um VU numa iteração. O k6 repete isto em loop.
  • http.get / http.post / …: as requisições.
  • check(): o que conta como resposta certa.

Mais duas de apoio: sleep() (o think time) e group() (organiza o relatório por trecho do fluxo).

Item por item, com exemplo

Os trechos abaixo são pedaços soltos, só pra explicar a sintaxe de cada peça, não são pra rodar isolados nem colar no terminal. Pra que servem, na prática: todos eles aparecem, montados, no arquivo real scripts/02_anatomia.js (já vem pronto no projeto que você baixou). Abra esse arquivo no VS Code do lado desta página e reconheça cada peça: o export default function, os http.post/http.get, os check. É nesse arquivo real que você vai editar e rodar, no Exercício logo abaixo.

export default function () { … }

🧩 trecho de exemplo: JavaScript pra estudar ou colar num arquivo .js, não é comando de terminal

export default function () {
  // tudo aqui dentro = 1 iteracao de 1 VU. Com vus:5, rodam 5 em paralelo.
  const r = http.get(`${BASE}/produtos`);
  sleep(1);
}

É a única função obrigatória. O que estiver fora dela (imports, const BASE = …, ler arquivo) roda uma vez, no "contexto de init"; o que está dentro roda a cada iteração.

http.get(url, params) / http.post(url, corpo, params)

🧩 trecho de exemplo: JavaScript pra estudar ou colar num arquivo .js, não é comando de terminal

const login = http.post(
  `${BASE}/login`,
  JSON.stringify({ usuario: `qa_${__VU}` }),          // corpo (string)
  { headers: { "Content-Type": "application/json" } } // params
);
const token = login.json("token");   // le um campo do JSON da resposta

A resposta traz .status, .body, .headers, .timings e .json("caminho"). __VU é o número do VU (1, 2, 3…), útil pra gerar dado diferente por usuário.

check(resposta, { rótulo: fn, … })

🧩 trecho de exemplo: JavaScript pra estudar ou colar num arquivo .js, não é comando de terminal

check(r, {
  "status 201": (res) => res.status === 201,
  "resposta traz id": (res) => res.json("id") !== undefined,
});

Cada função devolve true/false. Diferente de um assert, um check falso não interrompe a iteração, apenas alimenta a métrica checks (o "% ok" do resumo). Pra falhar o teste de verdade, é threshold (Módulo 3).

sleep(segundos): think time

🧩 trecho de exemplo: JavaScript pra estudar ou colar num arquivo .js, não é comando de terminal

const r = http.get(`${BASE}/produtos`);
check(r, { "produtos 200": (res) => res.status === 200 });
sleep(1);   // o "usuario" leva ~1s olhando a vitrine antes do proximo passo

Sem sleep, cada VU dispara requisições sem pausa, isso mede o servidor no talo, não usuários reais. Com think time, N VUs se parecem com N pessoas. Dá pra variar: sleep(Math.random() * 2).

options: a forma da carga

🧩 trecho de exemplo: JavaScript pra estudar ou colar num arquivo .js, não é comando de terminal

export const options = {
  vus: 5,             // 5 usuarios virtuais simultaneos
  duration: "20s",    // durante 20s (cada VU repete o fluxo em loop)
  thresholds: {
    http_req_failed: ["rate<0.05"],
  },
};

Aqui você escolhe entre duration (roda por X tempo) ou iterations (roda X vezes no total). O Módulo 3 troca isso por stages, que desenha uma rampa.

group("nome", fn) + tags

🧩 trecho de exemplo: JavaScript pra estudar ou colar num arquivo .js, não é comando de terminal

group("navegar", function () {
  const r = http.get(`${BASE}/produtos`, { tags: { tipo: "leitura" } });
  check(r, { "produtos 200": (res) => res.status === 200 });
});

group agrupa as métricas daquele trecho no relatório (útil pra saber se a lentidão está no "login" ou no "checkout"). A tag { tipo: "leitura" } cria uma sub-métrica: dá pra ter um threshold só das requisições de leitura: "http_req_duration{tipo:leitura}": ["p(95)<600"].

O script completo

Está em scripts/02_anatomia.js: login → navegar → comprar, com group em cada etapa, o token do login reaproveitado na compra, e um threshold na sub-métrica de leitura. Rode com o mock ligado:

k6 run scripts/02_anatomia.js
python verificar.py 2

No resumo vão aparecer VUs (pico): 5 e a sub-métrica http_req_duration{tipo:leitura} com o próprio p95.

Exercício

No grupo comprar do scripts/02_anatomia.js, adicione um terceiro check que verifica se o pedido volta com status igual a "novo". Rode de novo e confirme python verificar.py 2 com tudo [ok] e checks ok perto de 100%. Solução em trilha-5/GABARITO.md.

Olhar de QA

Aqui mora a confusão que faz muita gente ter um teste de carga que nunca reprova: check() não falha o teste. Ele alimenta uma métrica; quem reprova é o threshold do próximo módulo. E preste atenção no realismo do roteiro: sem think time e com dado fixo, você mede o cache de um registro só, e conclui que o sistema aguenta muito mais gente do que ele realmente aguenta.

Terminou este módulo? Marque: o ✓ aparece no índice da trilha e a barra de progresso anda no começo do site. Fica salvo só no seu navegador.