QA Learning / k6

Módulo 1: Preparar e primeiro teste

O que é teste de carga, instalar o k6, e rodar um smoke test contra o alvo de treino.

O que é teste de carga

Os testes que você já fez respondem "o sistema faz a coisa certa?". Teste de carga responde outra pergunta: "o sistema aguenta muita gente fazendo a coisa certa ao mesmo tempo?". É teste não-funcional: ninguém olha se a resposta está correta, olha-se quanto tempo ela demora e quantas falham quando a pressão sobe.

Três resultados típicos que ele entrega:

  • o tempo de resposta sob carga (normalmente o p95: o valor que 95% das requisições não ultrapassam);
  • a taxa de erro quando a carga aperta (respostas 5xx, timeouts);
  • a capacidade: quantas requisições por segundo antes de degradar.

Como QA, isso vira portão: "o checkout tem que responder em menos de 800ms no p95 com 200 usuários" é um critério que o k6 verifica sozinho e que o CI pode reprovar.

Os 3 conceitos que sustentam tudo

  • VU (virtual user): um "usuário" simulado. Cada VU roda o seu roteiro em loop, de forma independente e paralela. 50 VUs = 50 roteiros acontecendo ao mesmo tempo.
  • Iteração: uma passada completa pelo roteiro (a função default do script). Um VU faz uma iteração atrás da outra.
  • Duração / nº de iterações: o quanto a carga dura. Ou você fixa o tempo (duration: "30s") ou o total de iterações (iterations: 100).

Think time (sleep()): a pausa que um humano real faz entre uma ação e outra. Sem ela, 10 VUs viram um martelo irreal batendo sem parar; com ela, 10 VUs parecem 10 pessoas navegando.

1. Instalar o k6

O k6 é um programa único, grátis e open source. Não roda no navegador, é no terminal.

Windows:

winget install k6 --source winget

macOS: brew install k6. Linux: instruções em grafana.com/docs/k6.

Feche e reabra o terminal e confirme:

k6 version

Se der "k6 não é reconhecido" mesmo depois de reabrir o terminal (comum no Windows): fechar a janela do terminal não é suficiente porque o PATH atualizado só chega a processos novos depois que a sessão é renovada. Se você usa VS Code, abrir uma aba de terminal nova não conta: ela herda o PATH do VS Code que já estava aberto antes da instalação; feche o VS Code inteiro (todas as janelas) e reabra, ou melhor, reinicie o computador (ou saia e entre de novo na conta do Windows) e tente outra vez. Para testar sem reiniciar agora, em cada aba de terminal onde for usar o k6:

$env:Path += ";C:\Program Files\k6\"
k6 version

(Esse comando vale só para a aba atual do terminal: se abrir outra aba, precisa rodar de novo. Depois de reiniciar o computador, k6 version volta a funcionar sozinho em qualquer terminal, sem precisar dele.)

Se o winget não cooperar: baixe o .zip em github.com/grafana/k6/releases, extraia o k6.exe numa pasta e chame por caminho completo. Não precisa de admin.

2. Pegar o projeto e subir o alvo

Não precisa de Git nem de conta no GitHub:

Baixar só esta trilha (.zip) 15 KB · só a pasta trilha-5/

Se preferir clonar com Git, um aviso: baixa o repositório inteiro, cerca de 4 MB com o site, as outras trilhas e todo o histórico. Só compensa se você for fazer a Trilha 6 (CI/CD), que precisa do repositório pra rodar o pipeline. Para esta trilha, os 15 KB do botão bastam.

git clone https://github.com/ezequiel-dawud/HardSkillsQA.git

Agora abra dois terminais e, em cada um, entre na pasta da trilha:

cd trilha-5

Todos os comandos daqui pra frente supõem que você está dentro de trilha-5/. Se der can't open file ou No such file, é quase sempre isso: você está na pasta de cima.

Terminal 1: o alvo de treino (um HTTP falso que fica mais lento sob carga):

python mock/servidor.py

Deixe rodando. Ele escuta em http://127.0.0.1:8787. Não precisa instalar nada: é só biblioteca padrão do Python.

Enquanto o k6 roda, pode aparecer um traceback longo aqui terminando em ConnectionResetError ou WinError 10054. É inofensivo: é só o jeito como o k6 fecha a conexão, que o servidor de testes do Python registra como erro mas não afeta as próximas requisições. O servidor continua no ar. Confira pelo resumo que aparece no Terminal 2.

3. O primeiro teste: um smoke

O smoke test é o mais simples que existe: 1 VU, poucas iterações, só pra ver se o alvo está de pé e o script funciona. Ninguém roda carga de verdade sem passar por aqui. O arquivo já vem pronto no projeto; isto aqui é só pra você ver o conteúdo, não precisa digitar nem colar isto no terminal:

📄 arquivo já existe em scripts/01_smoke.js, não cole no terminal

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

const BASE = __ENV.BASE_URL || "http://127.0.0.1:8787";

export const options = {
  vus: 1,
  iterations: 10,
  thresholds: {
    http_req_failed: ["rate<0.01"],     // menos de 1% de erro
    http_req_duration: ["p(95)<800"],   // 95% das respostas abaixo de 800ms
  },
};

export default function () {
  const r = http.get(`${BASE}/produtos`);
  check(r, {
    "status e 200": (res) => res.status === 200,
    "veio a lista de produtos": (res) => Array.isArray(res.json("produtos")),
  });
  sleep(1);
}

Terminal 2, de dentro de trilha-5/:

k6 run scripts/01_smoke.js

4. Ler o resumo

No fim, o script imprime um resumo enxuto (e grava resumo.json pro corretor). As linhas que importam:

  requisicoes.......: 100
  req/s.............: 19.7
  duracao media.....: 16.2ms
  duracao p95.......: 22.1ms      <- 95% ficaram abaixo disso
  falhas (erro).....: 0.00%       <- % de respostas que falharam
  checks ok.........: 100.00%     <- % de check() que passaram
  VUs (pico)........: 1
  iteracoes.........: 10
  portao (thresholds): ok         <- nenhuma regra foi violada
  • p95 é a métrica de tempo que se usa, porque a média engana quando tem uns poucos picos altos.
  • falhas (erro) é http_req_failed: requisições com status ruim ou sem resposta.
  • checks ok: um check() que falha não derruba o teste (diferente de um assert); só baixa esse percentual.
  • portão: se algum threshold for violado, aqui aparece REPROVADO e o k6 run sai com código de erro. É o que o CI olha.

Rode o corretor pra conferir os critérios do módulo:

python verificar.py 1

Sem subir o mock (alvo público)

Os scripts leem BASE_URL do ambiente. Pra treinar contra o alvo público do k6, sem abrir o Terminal 1:

k6 run -e BASE_URL=https://quickpizza.grafana.com scripts/01_smoke.js

O mock local é melhor a partir do Módulo 3: você controla a lentidão e o corretor consegue checar o lado do servidor.

Exercício

Com o mock ligado, rode 01_smoke.js como está e confirme python verificar.py 1 com tudo [ok]. Depois troque iterations: 10 por iterations: 30 e rode de novo. Observe o que muda no resumo (só requisicoes e a duração total) e o que não muda (p95, taxa de erro). O gabarito está em trilha-5/GABARITO.md.

Olhar de QA

Teste de carga só é útil quando a meta é um número. "Tem que ser rápido" não reprova nada; "o checkout responde em menos de 800ms no p95 com 200 usuários simultâneos" é um critério que a ferramenta verifica sozinha e o pipeline faz valer. A pergunta mais importante do teste de carga é feita antes de escrever o script: qual é o número que define passar ou reprovar, e quem decidiu esse número?

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.