Testes de Load/Stress: Garantindo Performance sob Carga

Testes Automatizados · 6 de julho de 2026

📖 5 min de leitura

Tipos de Teste de Carga

Load Testing

Verifica comportamento sob carga esperada.

Carga: 1000 usuários simultâneos
Duração: 30 minutos
Métrica: P95 < 500ms

Stress Testing

Vai além dos limites normais.

Carga: 1000 → 2000 → 5000 usuários
Objetivo: Encontrar ponto de quebra

Spike Testing

Picos súbitos de carga.

Normal: 500 usuários
Spike: 5000 usuários em 5 segundos
Recovery: 500 usuários

Soak Testing

Carga sustentada por longo período.

Carga: 1000 usuários
Duração: 8 horas
Objetivo: Memory leaks, degradação

k6 – Modern Load Testing

Instalação

# macOS
brew install k6

# Linux
sudo apt install k6

# Windows
choco install k6

Script Básico

// load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
stages: [
{ duration: '2m', target: 100 }, // Ramp-up
{ duration: '5m', target: 100 }, // Steady
{ duration: '2m', target: 200 }, // Stress
{ duration: '5m', target: 200 }, // Steady
{ duration: '2m', target: 0 }, // Ramp-down
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} < 500ms
http_req_failed: ['rate<0.01'], // < 1{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} errors
checks: ['rate>0.95'], // > 95{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} checks pass
},
};

const BASE_URL = 'https://api.exemplo.com';

export default function () {
// Login
const loginRes = http.post(${BASE_URL}/auth/login, {
email: 'user@example.com',
password: 'password123',
});

check(loginRes, {
'login status 200': (r) => r.status === 200,
'has token': (r) => r.json('token') !== undefined,
});

const token = loginRes.json('token');

// Get products
const productsRes = http.get(${BASE_URL}/products, {
headers: { 'Authorization': Bearer ${token} },
});

check(productsRes, {
'products status 200': (r) => r.status === 200,
'has products': (r) => r.json('items').length > 0,
});

sleep(1);
}

Cenários Complexos

// scenarios.js
import http from 'k6/http';
import { check, group } from 'k6/http';
import { Rate, Trend } from 'k6/metrics';

const errorRate = new Rate('errors');
const apiLatency = new Trend('api_latency');

export const options = {
scenarios: {
// Smoke test
smoke: {
executor: 'constant-vus',
vus: 10,
duration: '1m',
tags: { test_type: 'smoke' },
},

// Load test
load: {
executor: 'ramping-vus',
startVUs: 0,
stages: [
{ duration: '2m', target: 100 },
{ duration: '5m', target: 100 },
{ duration: '2m', target: 0 },
],
tags: { test_type: 'load' },
},

// Stress test
stress: {
executor: 'ramping-arrival-rate',
startRate: 1,
timeUnit: '1s',
preAllocatedVUs: 100,
maxVUs: 500,
stages: [
{ duration: '2m', target: 10 },
{ duration: '5m', target: 50 },
{ duration: '2m', target: 100 },
{ duration: '1m', target: 0 },
],
tags: { test_type: 'stress' },
},

// Spike test
spike: {
executor: 'ramping-vus',
startVUs: 0,
stages: [
{ duration: '30s', target: 100 },
{ duration: '1m', target: 1000 }, // Spike!
{ duration: '30s', target: 1000 },
{ duration: '2m', target: 0 },
],
tags: { test_type: 'spike' },
},
},
};

export default function () {
const res = http.get('https://api.exemplo.com/health');

errorRate.add(res.status !== 200);
apiLatency.add(res.timings.duration);
}


JMeter – Enterprise Load Testing

Instalação

# Download
wget https://jmeter.apache.org/download_jmeter.cgi

# Run
./bin/jmeter.sh

Plano de Teste (GUI)

Test Plan
├── Thread Group (100 users, 10s ramp-up, loop 10)
│   ├── HTTP Request Defaults
│   │   └── Server: api.exemplo.com
│   │
│   ├── Once Only Controller
│   │   └── Login Request
│   │       └── POST /auth/login
│   │
│   ├── Recording Controller
│   │   └── GET /products
│   │   └── GET /products/{id}
│   │   └── POST /orders
│   │
│   └── Listeners
│       ├── Summary Report
│       ├── View Results Tree
│       ├── Aggregate Report
│       └── Graph Results

JMeter CLI

# Run non-GUI
jmeter -n -t test-plan.jmx -l results.jtl -e -o html-report

# With specific properties
jmeter -n -t api-test.jmx
-Jthreads=100
-Jrampup=10
-Jduration=300
-l results.jtl

Distributed Testing

# jmeter-server (on slave machines)
jmeter-server -Djava.rmi.server.hostname=192.168.1.100

# Run distributed
jmeter -n -t test.jmx
-R192.168.1.100,192.168.1.101,192.168.1.102
-l results.jtl


Gatling – Scala-based Load Testing

Instalação

# Download
wget https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/3.10.5/gatling-charts-highcharts-bundle-3.10.5.zip
unzip gatling-charts-highcharts-bundle-3.10.5.zip

Script Scala

// src/test/scala/LoadSimulation.scala
package simulations

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
import io.gatling.core.structure.ScenarioBuilder

class ApiLoadSimulation extends Simulation {

val httpProtocol = http
.baseUrl("https://api.exemplo.com")
.acceptHeader("application/json")
.contentTypeHeader("application/json")
.disableCaching

val userFeeder = csv("users.csv").circular.random

val loginScenario: ScenarioBuilder = scenario("Login Flow")
.feed(userFeeder)
.exec(
http("Login")
.post("/auth/login")
.body(StringBody(
"""{"email":"${email}","password":"${password}"}"""
)).asJson
.check(jsonPath("$.token").saveAs("authToken"))
)
.pause(1)
.exec(
http("Get Products")
.get("/products")
.header("Authorization", "Bearer ${authToken}")
.check(status.is(200))
)
.pause(1)
.exec(
http("Create Order")
.post("/orders")
.header("Authorization", "Bearer ${authToken}")
.body(StringBody(
"""{"productId":1,"quantity":2}"""
)).asJson
.check(status.is(201))
)

setUp(
loginScenario
.inject(
rampUsers(100).during(30.seconds),
constantUsersPerSec(50).during(5.minutes),
rampUsers(100).during(30.seconds)
)
.protocols(httpProtocol)
)
.assertions(
global.responseTime.percentile(95).lt(500),
global.successfulRequests.percent.gt(99)
)
.thresholds(
http("Login").responseTime.percentile(99).lt(1000)
)
}


Interpreting Results

Key Metrics

Métrica Significado Target
P95 Latency 95{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} das requisições < 500ms
P99 Latency 99{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} das requisições < 1s
Throughput Req/s > 1000
Error Rate {6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} falhas < 1{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442}
CPU Utilização < 80{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442}
Memory Utilização < 85{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442}

Finding Bottlenecks

// k6 com métricas customizadas
import { Trend } from 'k6/metrics';

const dbLatency = new Trend('db_query_duration');
const externalLatency = new Trend('external_api_duration');

export default function () {
const start = Date.now();
// DB query
const dbRes = http.get(${BASE_URL}/db);
dbLatency.add(Date.now() - start);

// External API
const extStart = Date.now();
const extRes = http.get('https://external-api.com/data');
externalLatency.add(Date.now() - extStart);
}


Conclusão

Testes de carga são essenciais para garantir performance. As chaves são:

  1. Definir objetivos claros – SLAs e thresholds
  2. Simular realista – Dados e comportamento reais
  3. Monitorar infra – CPU, memória, rede
  4. Analisar resultados – P95, P99, throughput
  5. Testar regularmente – CI/CD integrado