DEV Community

Cover image for Teste de Carga com Artillery: Guia Prático para APIs
Lucas
Lucas

Posted on • Originally published at apidog.com

Teste de Carga com Artillery: Guia Prático para APIs

Artillery é um kit de teste de carga open source, baseado em Node.js, que gera tráfego concorrente contra APIs a partir de scripts YAML. Você define fases de carga, descreve o fluxo das requisições, executa artillery run script.yml e analisa percentis de latência, taxa de requisições e erros. Neste guia, você vai instalar o Artillery v2, criar um teste real, executar a carga, exportar resultados no formato atual do v2 e integrar tudo ao CI.

Experimente o Apidog hoje

O que é Artillery e quando usar

Artillery simula usuários virtuais, ou VUs, acessando seus endpoints. Cada VU executa um cenário: uma sequência de requisições parecida com o comportamento de um cliente real.

Use Artillery quando precisar responder perguntas como:

  • Qual é a latência p95 com 50 requisições por segundo?
  • Em qual taxa de chegada os erros começam?
  • A API permanece estável durante 5 minutos de carga sustentada?
  • O sistema degrada gradualmente ou falha de forma abrupta?

A principal vantagem é o modelo declarativo. Em vez de escrever manualmente loops de concorrência, você descreve a carga em YAML. Como roda sobre Node.js, o mesmo teste funciona no seu laptop, em staging e em CI.

Se você ainda está comparando ferramentas, veja este resumo das principais ferramentas de teste de carga e esta comparação de software de teste de carga, que cobrem trade-offs entre k6, JMeter, Gatling e outras opções.

Instalar Artillery v2

O pacote npm se chama artillery. Instale a versão mais recente globalmente:

npm install -g artillery@latest
artillery version
Enter fullscreen mode Exit fullscreen mode

Você precisa de uma versão LTS recente do Node.js. O Artillery funciona em Windows, macOS e Linux.

Se preferir não instalar globalmente, use npx:

npx artillery@latest run script.yml
Enter fullscreen mode Exit fullscreen mode

Criar um script de teste Artillery

Um teste Artillery é um arquivo YAML com duas seções principais:

  • config: define alvo, fases de carga, variáveis e dados.
  • scenarios: define o que cada usuário virtual executa.

Crie um arquivo script.yml:

config:
  target: "https://api.example.com"
  phases:
    - name: "Warm up"
      duration: 60
      arrivalRate: 5
    - name: "Ramp to peak"
      duration: 120
      arrivalRate: 5
      rampTo: 50
    - name: "Sustained load"
      duration: 300
      arrivalRate: 50
      maxVusers: 500

  variables:
    productId:
      - "1001"
      - "1002"

scenarios:
  - name: "Browse and create order"
    flow:
      - get:
          url: "/v1/products/{{ productId }}"
      - post:
          url: "/v1/orders"
          json:
            productId: "{{ productId }}"
            quantity: 2
Enter fullscreen mode Exit fullscreen mode

Esse teste faz três coisas:

  1. Aquece a API com 5 novos VUs por segundo por 60 segundos.
  2. Aumenta gradualmente de 5 para 50 novos VUs por segundo em 120 segundos.
  3. Mantém 50 novos VUs por segundo por 300 segundos.

Como configurar config

config.target é o host base. Cada url nos cenários é concatenada com esse alvo.

Exemplo:

config:
  target: "https://api.example.com"
Enter fullscreen mode Exit fullscreen mode

Com a etapa:

- get:
    url: "/v1/products/1001"
Enter fullscreen mode Exit fullscreen mode

A requisição final será para:

https://api.example.com/v1/products/1001
Enter fullscreen mode Exit fullscreen mode

As fases de carga ficam em config.phases:

phases:
  - duration: 60
    arrivalRate: 5
  - duration: 120
    arrivalRate: 5
    rampTo: 50
Enter fullscreen mode Exit fullscreen mode

Campos mais usados:

Campo Função
duration Duração da fase, em segundos ou formato como "5m"
arrivalRate Quantos novos VUs iniciam por segundo
rampTo Aumenta linearmente a taxa até esse valor
arrivalCount Número fixo de VUs distribuídos durante a fase
maxVusers Limite máximo de VUs simultâneos
name Nome exibido na saída

Atenção: duration controla por quanto tempo o Artillery continua criando novos VUs. O teste pode continuar depois disso se VUs iniciados no fim da fase ainda estiverem executando seus fluxos.

Como configurar scenarios

scenarios é uma lista de fluxos possíveis. Cada cenário contém um flow, que é a sequência de passos executada por um VU.

scenarios:
  - name: "Create order"
    flow:
      - get:
          url: "/v1/products/{{ productId }}"
      - post:
          url: "/v1/orders"
          json:
            productId: "{{ productId }}"
            quantity: 2
Enter fullscreen mode Exit fullscreen mode

Os passos usam verbos HTTP:

  • get
  • post
  • put
  • patch
  • delete

Para enviar corpo JSON:

- post:
    url: "/v1/orders"
    json:
      productId: "{{ productId }}"
      quantity: 2
Enter fullscreen mode Exit fullscreen mode

A sintaxe {{ productId }} injeta uma variável.

Você também pode usar weight para controlar a probabilidade de escolha de cada cenário:

scenarios:
  - name: "Browse"
    weight: 80
    flow:
      - get:
          url: "/v1/products"

  - name: "Create order"
    weight: 20
    flow:
      - post:
          url: "/v1/orders"
          json:
            productId: "1001"
            quantity: 1
Enter fullscreen mode Exit fullscreen mode

Usar dados de um CSV

Variáveis inline servem para smoke tests. Para testes mais realistas, use um CSV com config.payload.

Exemplo de users.csv:

email,password
user1@example.com,pass123
user2@example.com,pass456
Enter fullscreen mode Exit fullscreen mode

Script:

config:
  target: "https://api.example.com"
  payload:
    path: "./users.csv"
    fields:
      - "email"
      - "password"
  phases:
    - duration: 120
      arrivalRate: 20

scenarios:
  - name: "Login"
    flow:
      - post:
          url: "/login"
          json:
            email: "{{ email }}"
            password: "{{ password }}"
Enter fullscreen mode Exit fullscreen mode

Cada VU escolhe uma linha do CSV, e os nomes das colunas viram variáveis disponíveis no fluxo.

Executar o teste

Execute o script:

artillery run script.yml
Enter fullscreen mode Exit fullscreen mode

Sobrescreva o alvo sem editar o YAML:

artillery run --target https://staging.example.com script.yml
Enter fullscreen mode Exit fullscreen mode

Passe variáveis via JSON:

artillery run -v '{ "productId": ["1001","1002"] }' script.yml
Enter fullscreen mode Exit fullscreen mode

Flags úteis:

Flag Uso
--target, -t Sobrescreve config.target
--environment, -e Seleciona um ambiente em config.environments
--config, -c Carrega configuração de outro arquivo
--insecure, -k Ignora verificação TLS para certificados autoassinados

Exemplo com ambientes:

config:
  target: "https://api.example.com"
  environments:
    staging:
      target: "https://staging.example.com"
    production:
      target: "https://api.example.com"
  phases:
    - duration: 60
      arrivalRate: 10

scenarios:
  - flow:
      - get:
          url: "/health"
Enter fullscreen mode Exit fullscreen mode

Execute contra staging:

artillery run -e staging script.yml
Enter fullscreen mode Exit fullscreen mode

Ler os resultados

Durante a execução, o Artillery imprime métricas agregadas aproximadamente a cada 10 segundos. No final, ele exibe um resumo.

Foque nestes números:

  • Taxa de requisições: throughput realmente alcançado.
  • p50: mediana da latência.
  • p95: latência dos 5% mais lentos.
  • p99: cauda extrema da latência.
  • Erros: falhas, timeouts e respostas não 2xx.

Não avalie apenas a média. Uma média aceitável pode esconder um p99 de vários segundos.

Interprete assim:

  • p95 sobe durante o ramp-up: a API pode estar saturando cedo.
  • erros aparecem apenas na fase sustentada: possível vazamento, fila acumulando ou limite de recurso.
  • throughput não acompanha arrivalRate: o sistema ou o gerador de carga pode ter atingido limite.
  • p99 instável: investigue dependências externas, banco de dados, filas ou cold paths.

Para um guia mais amplo sobre métricas, veja este guia de teste de desempenho de API.

Gerar relatório no Artillery v2

Tutoriais antigos podem confundir aqui.

No Artillery v2, isto ainda funciona:

artillery run --output report.json script.yml
Enter fullscreen mode Exit fullscreen mode

Isso grava um arquivo JSON com resultados legíveis por máquina.

Mas isto não funciona mais na CLI atual:

artillery report report.json
Enter fullscreen mode Exit fullscreen mode

O comando artillery report, que convertia JSON em HTML, foi removido da CLI do Artillery. O gerador HTML foi descontinuado e não há plano de retorno.

Hoje, você tem três caminhos.

Opção 1: analisar o JSON com jq

Exemplo para extrair o p95 agregado:

jq '.aggregate.summaries["http.response_time"].p95' report.json
Enter fullscreen mode Exit fullscreen mode

Você pode transformar isso em gate de CI:

P95=$(jq '.aggregate.summaries["http.response_time"].p95' report.json)

if (( $(echo "$P95 > 500" | bc -l) )); then
  echo "p95 acima do limite: ${P95}ms"
  exit 1
fi
Enter fullscreen mode Exit fullscreen mode

Opção 2: usar Artillery Cloud

Para dashboard hospedado, use --record com sua chave de API:

artillery run --record --key $ARTILLERY_CLOUD_API_KEY script.yml
Enter fullscreen mode Exit fullscreen mode

Opção 3: enviar métricas para sua observabilidade

Use o plugin publish-metrics ou OpenTelemetry para enviar latência, throughput e erros para a mesma stack usada em produção.

Executar Artillery em CI

Como o Artillery é uma CLI Node.js, ele encaixa bem em pipelines.

Exemplo de GitHub Actions:

name: Load test

on: [workflow_dispatch]

jobs:
  artillery:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "lts/*"

      - run: npm install -g artillery@latest

      - run: artillery run --output report.json script.yml

      - uses: actions/upload-artifact@v4
        with:
          name: artillery-report
          path: report.json
Enter fullscreen mode Exit fullscreen mode

Esse workflow roda manualmente com workflow_dispatch. Para testes de carga pesados, isso costuma ser melhor do que executar em todo commit, porque o teste consome tempo, rede e recursos reais.

Você também pode adicionar um gate de latência:

      - name: Fail if p95 is too high
        run: |
          P95=$(jq '.aggregate.summaries["http.response_time"].p95' report.json)
          echo "p95=${P95}ms"

          if (( $(echo "$P95 > 500" | bc -l) )); then
            echo "p95 acima do limite permitido"
            exit 1
          fi
Enter fullscreen mode Exit fullscreen mode

Onde o Apidog entra: testes funcionais e gate de CI

Artillery responde:

A API aguenta esse volume de tráfego?

Isso é teste de carga e desempenho.

Outra pergunta importante é:

A API ainda retorna respostas corretas depois desta mudança?

Isso é teste funcional e de regressão. É onde o Apidog se encaixa.

Apidog é uma plataforma de API para design, depuração, mocking, documentação e testes automatizados. Seus cenários de teste agrupam endpoints em etapas lógicas com condições como if, for e foreach, permitindo validar:

  • códigos de status;
  • corpos de resposta;
  • contratos;
  • fluxos entre endpoints;
  • regressões em CI.

O limite é importante: o Apidog inclui recurso de teste de desempenho, mas limitado a até 100 usuários virtuais. Isso pode ajudar a identificar regressões óbvias, mas não substitui o Artillery para alta concorrência.

Para carga distribuída e modelada por código em grande escala, use Artillery. Para validação funcional e de contrato em CI, use Apidog.

Essa separação também aparece no artigo sobre testes de carga de APIs sem Python, e a mecânica do recurso de 100 VUs do Apidog é abordada em testes de desempenho de API no Apidog.

Executar testes do Apidog via CLI

Instale a CLI:

npm install -g apidog-cli
Enter fullscreen mode Exit fullscreen mode

Execute um cenário funcional ou de regressão:

apidog run \
  --access-token $APIDOG_ACCESS_TOKEN \
  -t <TEST_SCENARIO_ID> \
  -e <ENVIRONMENT_ID> \
  -r cli,junit \
  --out-dir ./apidog-reports
Enter fullscreen mode Exit fullscreen mode

Parâmetros principais:

Flag Função
--access-token Token de acesso do Apidog
-t ID do cenário de teste
-e ID do ambiente
-r cli,junit Saída no console e relatório JUnit
--out-dir Diretório dos relatórios

O relatório JUnit pode ser lido por sistemas de CI para bloquear merges quando testes funcionais falharem.

Para um passo a passo, veja o tutorial da CLI do Apidog. Para padrões de pipeline, veja estas melhores práticas de CI/CD para testes de API.

Estratégia prática

Use as duas camadas:

  1. Artillery

    • carga;
    • concorrência;
    • throughput;
    • p95/p99;
    • saturação.
  2. Apidog

    • testes funcionais;
    • regressão;
    • contrato;
    • validação de respostas;
    • gate de CI.

Um pipeline comum fica assim:

Pull request
  └── testes funcionais com Apidog

Merge em main
  └── smoke tests

Execução manual ou agendada
  └── teste de carga com Artillery
Enter fullscreen mode Exit fullscreen mode

Quer testes funcionais e de contrato protegendo seu CI junto com execuções de carga do Artillery? Baixe o Apidog gratuitamente e crie seu primeiro cenário de teste.

Perguntas frequentes

O que é teste de carga Artillery?

Teste de carga Artillery é a prática de usar a CLI open source Artillery para simular muitos usuários virtuais concorrentes acessando uma API. Você descreve a carga e o fluxo de requisições em YAML, executa o teste e mede latência, throughput e erros.

Artillery é gratuito e open source?

Sim. A CLI principal do Artillery é gratuita e open source, distribuída no npm como o pacote artillery. Também existe o Artillery Cloud, uma oferta hospedada para dashboards e resultados, mas você pode executar testes localmente e em CI sem ela.

Como executar um teste de carga Artillery?

Instale com:

npm install -g artillery@latest
Enter fullscreen mode Exit fullscreen mode

Crie um script YAML com config e scenarios, depois execute:

artillery run script.yml
Enter fullscreen mode Exit fullscreen mode

O Artillery imprime métricas ao vivo durante a execução e um resumo no final.

Como gerar um relatório Artillery?

Use:

artillery run --output report.json script.yml
Enter fullscreen mode Exit fullscreen mode

Isso gera um JSON de resultados. O antigo comando artillery report para HTML foi removido. Para analisar resultados, use jq, Artillery Cloud ou envie métricas para sua stack de observabilidade.

Artillery, k6 ou JMeter: qual usar?

Todos suportam testes de carga em alta escala.

  • Artillery: YAML declarativo, Node.js, bom para equipes no ecossistema JavaScript.
  • k6: scripts em JavaScript com abordagem code-first.
  • JMeter: GUI, Java e grande ecossistema de plugins.

A comparação Gatling vs JMeter cobre trade-offs em mais detalhes. Escolha a ferramenta cujo modelo se adapta melhor à sua equipe e combine com testes funcionais em CI para cobertura completa.

Top comments (0)