<p><strong>Meta Description:</strong> Domine testes de performance: load testing, stress testing, spike testing e soak testing. Aprenda a usar JMeter, k6, Gatling e interprete resultados para otimizar seus sistemas.</p>

<hr>
<h2>Introdução aos Testes de Performance</h2>

<p>Testes de performance são testes não-funcionais que avaliam quão bem um sistema se comporta sob diferentes condições de carga, volume e estresse. São críticos para garantir que aplicações atendam aos requisitos de velocidade, escalabilidade e estabilidade.</p>

<h3>Por Que Testes de Performance São Essenciais?</h3>

<figure class="wp-block-table"><table>
<tr><th>Impacto</th><th>Dados</th></tr>
<tr><td><strong>Receita</strong></td><td>1 segundo de delay = 7{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} menos conversões</td></tr>
<tr><td><strong>Usuários</strong></td><td>53{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} abandonam site se &gt;3s para carregar</td></tr>
<tr><td><strong>Receita Amazon</strong></td><td>1 segundo de delay = $1.6B/ano em vendas</td></tr>
<tr><td><strong>Google</strong></td><td>500ms extra = 20{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} menos buscas</td></tr>
</table></figure>

<hr>
<h2>Tipos de Testes de Performance</h2>

<h3>1. Load Testing (Teste de Carga)</h3>

<p>Verifica o comportamento do sistema sob condições de carga esperadas em produção.</p>

<p><strong>Objetivos:</strong><br><ul><li>Medir tempos de resposta</li><ol><li>Verificar throughput máximo</li><br><li>Identificar bottlenecks</li><br><li>Validar SLAs</li><br></ol><br><strong>Exemplo de Cenário:</strong><br><pre><code>Carga esperada: 1000 usuários simultâneos<br>Horário de pico: 10:00-12:00 e 14:00-16:00<br>Transações por hora: 10.000<br></code></pre></p>

<h3>2. Stress Testing (Teste de Estresse)</h3>

<p>Avalia os limites do sistema além da capacidade normal.</p>

<p><strong>Objetivos:</strong><ol><li>Identificar ponto de quebra</li><br><li>Medir degradação graciosa</li><br><li>Verificar recovery</li><br><li>Testar failovers</li><br></ol><br><strong>Cenário:</strong><br><pre><code>Normal: 1000 usuários<br>Stress: 2000 → 3000 → 5000 → 8000 → 10000 usuários<br>Objetivo: Encontrar onde o sistema quebra<br></code></pre></p>

<h3>3. Spike Testing (Teste de Pico)</h3>

<p>Avalia reações a picos súbitos de carga.</p>

<pre><code>Carga normal: 1000 usuários
Pico: 5000 usuários em 5 segundos
Recovery: 1000 usuários
Padrão: On-off-on-off
</code></pre>

<h3>4. Soak Testing (Teste de Resistência)</h3>

<p>Executa carga sustentada por período prolongado.</p>

<p><strong>Problemas Detectados:</strong><ol><li>Memory leaks</li><br><li>Connection pool exhaustion</li><br><li>Log rotation issues</li><br><li>Database connection limits</li><br><li>Disk space issues</li><br></ol><br><strong>Duração:</strong> 8-24+ horas contínuas</p>

<h3>5. Endurance Testing</h3>

<p>Similar ao Soak, mas com foco em validação de SLAs por longo período.</p>

<hr>
<h2>Métricas de Performance</h2>

<h3>Métricas Principais</h3>

<figure class="wp-block-table"><table>
<tr><th>Métrica</th><th>Descrição</th><th>Target Típico</th></tr>
<tr><td><strong>Response Time (Avg)</strong></td><td>Tempo médio de resposta</td><td>&lt;2s para web, &lt;500ms para API</td></tr>
<tr><td><strong>Response Time (P95)</strong></td><td>95º percentil</td><td>&lt;3s</td></tr>
<tr><td><strong>Response Time (P99)</strong></td><td>99º percentil</td><td>&lt;5s</td></tr>
<tr><td><strong>Throughput</strong></td><td>Requisições por segundo</td><td>Conforme especificado</td></tr>
<tr><td><strong>Error Rate</strong></td><td>{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} de requisições com erro</td><td>&lt;1{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442}</td></tr>
<tr><td><strong>CPU Usage</strong></td><td>Utilização de CPU</td><td>&lt;80{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442}</td></tr>
<tr><td><strong>Memory Usage</strong></td><td>Utilização de memória</td><td>&lt;85{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442}</td></tr>
<tr><td><strong>Network I/O</strong></td><td>Largura de banda</td><td>Dentro de capacidade</td></tr>
<tr><td><strong>Disk I/O</strong></td><td>Operações de disco</td><td>&lt;70{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} capacidade</td></tr>
</table></figure>

<h3>Como Medir Percentis</h3>

<pre><code>Lista de tempos de resposta (ms):
[120, 150, 180, 200, 220, 250, 280, 300, 350, 400, 500, 600, 800, 1000]

<p>Média: 334ms<br>Mediana (P50): 275ms<br>P95: 800ms (5{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} acima = 800ms)<br>P99: 1000ms (1{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} acima = 1000ms)<br></code></pre></p>

<hr>
<h2>Ferramentas de Teste de Performance</h2>

<h3>1. Apache JMeter</h3>

<p><strong>Melhor para:</strong> Projetos enterprise, testes complexos</p>

<h4>Instalação e Configuração</h4>

<pre><code># Download JMeter
wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-5.6.3.tgz
tar -xzf apache-jmeter-5.6.3.tgz

<p># Executar (requer Java 8+)<br>cd apache-jmeter-5.6.3/bin<br>./jmeter.sh<br></code></pre></p>

<h4>Exemplo de Plano de Teste (GUI)</h4>

<pre><code>Test Plan
├── Thread Group (Users: 100, Ramp-up: 10s, Loop: 10)
│   ├── HTTP Request Defaults (Server: api.exemplo.com)
│   │   └── Path: /api/produtos
│   ├── HTTP Cookie Manager
│   ├── Listeners
│   │   ├── Summary Report
│   │   ├── View Results Tree
│   │   └── Graph Results
</code></pre>

<h4>Script JMeter (CLI)</h4>

<pre><code>

  
    
      API Load Test
    
    
      
        100
        10
        10
      
      
        
          api.exemplo.com
          GET
          /api/produtos
        
      
    
  

</code></pre>

<pre><code># Executar via CLI
./jmeter.sh -n -t api_test.jmx -l results.jtl -e -o html_report
</code></pre>

<h3>2. k6 (Grafana k6)</h3>

<p><strong>Melhor para:</strong> DevOps, scripts em JS, CI/CD integrado</p>

<h4>Instalação</h4>

<pre><code># macOS
brew install k6

<p># Linux<br>sudo gpg -k<br>sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69<br>echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list<br>sudo apt-get update<br>sudo apt-get install k6<br></code></pre></p>

<h4>Script k6 - Load Test Básico</h4>

<pre><code>// load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend } from 'k6/metrics';

<p>// Métricas customizadas<br>const errorRate = new Rate('errors');<br>const responseTime = new Trend('response_time');</p>

<p>export const options = {<br>  stages: [<br>    { duration: '2m', target: 100 },   // Ramp-up<br>    { duration: '5m', target: 100 },   // Steady state<br>    { duration: '2m', target: 200 },   // Stress<br>    { duration: '5m', target: 200 },   // Steady state<br>    { duration: '2m', target: 0 },     // Ramp-down<br>  ],<br>  thresholds: {<br>    http_req_duration: ['p(95)&lt;500&#039;],  // 95{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} das req &lt; 500ms<br>    http_req_failed: ['rate&lt;0.01&#039;],     // &lt; 1{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} de falhas<br>    errors: ['rate&lt;0.1&#039;],               // &lt; 10{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442} de erros<br>  },<br>};</p>

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

<p>export default function () {<br>  // Login para obter token<br>  const loginRes = http.post(<code>${BASE_URL}/auth/login</code>, {<br>    email: 'usuario@teste.com',<br>    password: 'senha123',<br>  });</p>

<p>check(loginRes, {<br>    'login status 200': (r) =&gt; r.status === 200,<br>    'token received': (r) =&gt; r.json('token') !== undefined,<br>  });</p>

<p>const token = loginRes.json('token');</p>

<p>// Listar produtos com token<br>  const productsRes = http.get(<code>${BASE_URL}/api/produtos</code>, {<br>    headers: {<br>      'Authorization': <code>Bearer ${token}</code>,<br>    },<br>  });</p>

<p>responseTime.add(productsRes.timings.duration);<br>  errorRate.add(productsRes.status !== 200);</p>

<p>check(productsRes, {<br>    'products status 200': (r) =&gt; r.status === 200,<br>    'products returned': (r) =&gt; r.json('data').length &gt; 0,<br>  });</p>

<p>sleep(1);<br>}<br></code></pre></p>

<h4>Script k6 - Spike Test</h4>

<pre><code>// spike-test.js
import http from 'k6/http';
import { check } from 'k6';

<p>export const options = {<br>  scenarios: {<br>    spike_test: {<br>      executor: 'ramping-vus',<br>      startVUs: 0,<br>      stages: [<br>        { duration: '10s', target: 100 },   // Normal<br>        { duration: '30s', target: 1000 },    // SPIKE!<br>        { duration: '30s', target: 1000 },   // Hold<br>        { duration: '10s', target: 100 },    // Recovery<br>        { duration: '10s', target: 0 },      // Cooldown<br>      ],<br>    },<br>  },<br>  thresholds: {<br>    http_req_duration: ['p(95)&lt;1000&#039;],<br>  },<br>};</p>

<p>export default function () {<br>  const res = http.get('https://api.exemplo.com/health');<br>  check(res, { 'status OK': (r) =&gt; r.status === 200 });<br>}<br></code></pre></p>

<h3>3. Gatling</h3>

<p><strong>Melhor para:</strong> Scala/Java, relatórios detalhados, CI/CD</p>

<h4>Instalação</h4>

<pre><code># 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
</code></pre>

<h4>Script Gatling (Scala)</h4>

<pre><code>// src/test/scala/LoadSimulation.scala
package simulations

<p>import io.gatling.core.Predef._<br>import io.gatling.http.Predef._</p>

<p>class LoadSimulation extends Simulation {</p>

<p>val baseUrl = "https://api.exemplo.com"</p>

<p>val httpConfig = http<br>    .baseUrl(baseUrl)<br>    .acceptHeader("application/json")<br>    .contentTypeHeader("application/json")</p>

<p>val userFeeder = csv("users.csv").random</p>

<p>val scn = scenario("API Load Test")<br>    .feed(userFeeder)<br>    .exec(<br>      http("Login")<br>        .post("/auth/login")<br>        .body(StringBody("""{"email":"${email}","password":"${password}"}"""))<br>        .check(jsonPath("$.token").saveAs("authToken"))<br>    )<br>    .pause(1)<br>    .exec(<br>      http("Get Products")<br>        .get("/api/produtos")<br>        .header("Authorization", "Bearer ${authToken}")<br>        .check(status.is(200))<br>    )<br>    .pause(1)<br>    .exec(<br>      http("Get Product Details")<br>        .get("/api/produtos/1")<br>        .header("Authorization", "Bearer ${authToken}")<br>        .check(status.is(200))<br>    )</p>

<p>setUp(<br>    scn.inject(<br>      rampUsers(100).during(30.seconds),<br>      constantUsersPerSec(50).during(60.seconds)<br>    )<br>  )<br>  .protocols(httpConfig)<br>  .thresholds(<br>    http_req_duration.p95.lt(500),<br>    http_req_duration.p99.lt(1000)<br>  )<br>}<br></code></pre></p>

<h3>4. Locust (Python)</h3>

<p><strong>Melhor para:</strong> Equipes Python, testes distribuídos</p>

<h4>Instalação</h4>

<pre><code>pip install locust
</code></pre>

<h4>Script Locust</h4>

<pre><code># locustfile.py
from locust import HttpUser, task, between, events
import random

<p>class APIClient(HttpUser):<br>    wait_time = between(1, 3)</p>

<p>def on_start(self):<br>        """Login antes de executar tarefas"""<br>        response = self.client.post("/auth/login", json={<br>            "email": "usuario@teste.com",<br>            "password": "senha123"<br>        })<br>        if response.status_code == 200:<br>            self.token = response.json()["token"]<br>        else:<br>            self.token = None</p>

<p>@task(3)<br>    def list_products(self):<br>        """Listar produtos (mais frequente)"""<br>        if self.token:<br>            self.client.get(<br>                "/api/produtos",<br>                headers={"Authorization": f"Bearer {self.token}"}<br>            )</p>

<p>@task(2)<br>    def get_product(self):<br>        """Detalhes de produto"""<br>        product_id = random.randint(1, 100)<br>        if self.token:<br>            self.client.get(<br>                f"/api/produtos/{product_id}",<br>                headers={"Authorization": f"Bearer {self.token}"}<br>            )</p>

<p>@task(1)<br>    def create_order(self):<br>        """Criar pedido (menos frequente)"""<br>        if self.token:<br>            self.client.post(<br>                "/api/pedidos",<br>                headers={"Authorization": f"Bearer {self.token}"},<br>                json={<br>                    "produto_id": random.randint(1, 100),<br>                    "quantidade": random.randint(1, 5)<br>                }<br>            )</p>

<p># Executar<br># locust -f locustfile.py --host=https://api.exemplo.com<br></code></pre></p>

<hr>
<h2>Cenários de Teste Common</h2>

<h3>1. E-commerce</h3>

<figure class="wp-block-table"><table>
<tr><th>Cenário</th><th>Usuários</th><th>Duração</th><th>Objetivo</th></tr>
<tr><td>Navegação</td><td>500</td><td>10 min</td><td>P95 &lt; 2s</td></tr>
<tr><td>Busca</td><td>200</td><td>5 min</td><td>Throughput &gt; 50/s</td></tr>
<tr><td>Checkout</td><td>100</td><td>15 min</td><td>P95 &lt; 5s</td></tr>
<tr><td>Pico Black Friday</td><td>2000</td><td>1 min</td><td>Sistema estável</td></tr>
</table></figure>

<h3>2. API REST</h3>

<figure class="wp-block-table"><table>
<tr><th>Endpoint</th><th>Load</th><th>Stress</th><th>Spike</th></tr>
<tr><td>GET /users</td><td>1000 rps</td><td>2000 rps</td><td>5000 rps</td></tr>
<tr><td>POST /orders</td><td>500 rps</td><td>1000 rps</td><td>2000 rps</td></tr>
<tr><td>GET /products</td><td>2000 rps</td><td>4000 rps</td><td>8000 rps</td></tr>
</table></figure>

<h3>3. Aplicação Web</h3>

<figure class="wp-block-table"><table>
<tr><th>Página</th><th>Target Load</th><th>P95 Target</th></tr>
<tr><td>Home</td><td>1000 concurrent</td><td>&lt;3s</td></tr>
<tr><td>Search</td><td>500 concurrent</td><td>&lt;2s</td></tr>
<tr><td>Product Page</td><td>800 concurrent</td><td>&lt;2.5s</td></tr>
<tr><td>Checkout</td><td>200 concurrent</td><td>&lt;5s</td></tr>
</table></figure>

<hr>
<h2>Interpretando Resultados</h2>

<h3>Identificando Bottlenecks</h3>

<h4>CPU Bound</h4>

<pre><code>Sintomas:<ol><li>CPU &gt; 90{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442}</li>
<li>Throughput não aumenta com mais usuários</li>
<li>Response time aumenta linearmente</li>
</ol>
Soluções:<ol><li>Otimizar algoritmos</li>
<li>Cachear resultados</li>
<li>Adicionar índices ao banco</li>
<li>Load balancing</li>
</ol></code></pre>

<h4>Memory Bound</h4>

<pre><code>Sintomas:<ol><li>Memory leak crescente</li>
<li>Garbage collection frequente</li>
<li>OOM errors</li>
</ol>
Soluções:<ol><li>Code review para memory leaks</li>
<li>Aumentar memória</li>
<li>Pool de objetos</li>
<li>Compactação de dados</li>
</ol></code></pre>

<h4>I/O Bound</h4>

<pre><code>Sintomas:<ol><li>Disk I/O 100{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442}</li>
<li>Network saturation</li>
<li>Queries lentas</li>
</ol>
Soluções:<ol><li>Cache de queries</li>
<li>Compressão de dados</li>
<li>CDN para estáticos</li>
<li>Read replicas</li>
</ol></code></pre>

<h3>Dashboard de Resultados</h3>

<pre><code>// Exemplo de parse de resultados JMeter para dashboard
const results = parseJMeterResults('results.jtl');

<p>const summary = {<br>  totalRequests: results.length,<br>  avgResponseTime: results.avg(r =&gt; r.elapsed),<br>  p95ResponseTime: results.percentile(95, r =&gt; r.elapsed),<br>  p99ResponseTime: results.percentile(99, r =&gt; r.elapsed),<br>  errorRate: results.filter(r =&gt; r.success === false).length / results.length,<br>  throughput: results.length / (results.max(r =&gt; r.timestamp) - results.min(r =&gt; r.timestamp)) * 1000,<br>};</p>

<p>console.log(`<br>=== Load Test Summary ===<br>Total Requests: ${summary.totalRequests}<br>Avg Response: ${summary.avgResponseTime}ms<br>P95 Response: ${summary.p95ResponseTime}ms<br>P99 Response: ${summary.p99ResponseTime}ms<br>Error Rate: ${(summary.errorRate * 100).toFixed(2)}{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442}<br>Throughput: ${summary.throughput.toFixed(2)} req/s<br>`);<br></code></pre></p>

<hr>
<h2>Melhores Práticas</h2>

<h3>Antes do Teste</h3>
<ol><li><strong>Definir objetivos claros</strong> - SLAs, thresholds</li>
<li><strong>Ambiente isolado</strong> - Não testar em produção</li>
<li><strong>Dados准备了</strong> - Massa de dados realista</li>
<li><strong>Baseline estabelecido</strong> - Métricas de referência</li>
<li><strong>Monitoramento configurado</strong> - APM tools</li>
</ol>
<h3>Durante o Teste</h3>
<ol><li><strong>Iniciar gradualmente</strong> - Ramp-up suave</li>
<li><strong>Monitorar em tempo real</strong> - Dashboards ativos</li>
<li><strong>Documentar incidentes</strong> - Timestamps e evidências</li>
<li><strong>Não tocar no ambiente</strong> - Interferência mínima</li>
<li><strong>Capturar métricas</strong> - Logs, monitoring, profiling</li>
</ol>
<h3>Após o Teste</h3>
<ol><li><strong>Analisar resultados</strong> - Correlacionar métricas</li>
<li><strong>Identificar bottlenecks</strong> - Root cause analysis</li>
<li><strong>Documentar achados</strong> - Relatório técnico</li>
<li><strong>Recomendar ações</strong> - Priorizadas por impacto</li>
<li><strong>Repetir testes</strong> - Validar otimizações</li>
</ol>
<hr>
<h2>Checklist de Teste de Performance</h2>

<h3>Preparação</h3>
<ol><li>[ ] Objetivos de teste definidos</li>
<li>[ ] SLAs documentados</li>
<li>[ ] Ambiente configurado</li>
<li>[ ] Dados de teste criados</li>
<li>[ ] Baselinecapturado</li>
<li>[ ] Monitoramento configurado</li>
</ol>
<h3>Execução</h3>
<ol><li>[ ] Teste piloto executado</li>
<li>[ ] Carga gradual aplicada</li>
<li>[ ] Métricas capturadas</li>
<li>[ ] Incidentes documentados</li>
<li>[ ] Logs coletados</li>
</ol>
<h3>Análise</h3>
<ol><li>[ ] Resultados analisados</li>
<li>[ ] Bottlenecks identificados</li>
<li>[ ] Recomendações formuladas</li>
<li>[ ] Relatório preparado</li>
<li>[ ] Ações priorizadas</li></ol></ul>

<hr>
<h2>Conclusão</h2>

<p>Testes de performance são essenciais para garantir que suas aplicações atendam às expectativas dos usuários em termos de velocidade, escalabilidade e estabilidade. A escolha da ferramenta certa depende do contexto do projeto, mas o mais importante é:<br><ol><li><strong>Testar regularmente</strong> - Não apenas antes de releases</li><br><li><strong>Definir SLAs claros</strong> - Métricas objetivas</li><br><li><strong>Analisar resultados</strong> - Não apenas coletar</li><br><li><strong>Otimizar continuamente</strong> - Melhoria progressiva</li><br><li><strong>Automatizar</strong> - CI/CD integrado</li><br></ol><br><hr><br><h3>FAQ</h3></p>

<p><strong>P: Quantos usuários devo simular no load test?</strong>  <br>R: Baseie-se em seus picos de uso real + margem de 20-30{6727d158e4474b0847515bd23a8ee4bebd5f1aac7a18bc968e51d8985dccb442}.</p>

<p><strong>P: Qual é o P95 ideal?</strong>  <br>R: Depende do tipo de aplicação. API: &lt;500ms, Web: &lt;3s, Mobile: &lt;2s.</p>

<p><strong>P: Como often devo executar load tests?</strong>  <br>R: Mínimo: antes de cada release. Ideal: diária com subset, semanal completa.</p>

<p><strong>P: Load test em produção é uma boa ideia?</strong>  <br>R: Somente com feature flags, canary deployments e monitoramento rigoroso.</p>