🛠️ Automatizando pruebas de rendimiento con n8n + K6.io + IA (POC)

11 September, 2025 | IA

En los equipos de QA y DevOps uno de los retos más frecuentes es entender hasta dónde aguanta una aplicación bajo carga antes de empezar a fallar. Las herramientas tradicionales permiten hacer pruebas de rendimiento, pero muchas veces requieren configuraciones estáticas.

¿Qué pasaría si pudiéramos automatizar este ajuste y dejar que un flujo inteligente vaya calibrando la prueba hasta encontrar el punto de quiebre?

En este artículo te comparto un Proof of Concept (POC) donde combino n8n, K6.io y un motor de IA para orquestar pruebas de rendimiento con auto-tuning. El objetivo no es reemplazar pipelines de CI/CD como GitHub Actions o Azure DevOps, sino explorar cómo la automatización puede ayudarnos a iterar más rápido, registrar métricas clave y detectar patrones de fallo de manera temprana.

Objetivo del POC

  • Ejecutar pruebas de carga con K6 en un contenedor aislado.
  • Recoger métricas clave (p95, throughput, errorRate).
  • Usar IA para decidir ajustes de parámetros en cada iteración.
  • Persistir resultados en PostgreSQL.
  • Consolidar la información en un reporte final.

Arquitectura del flujo

  1. Inicialización de parámetros:
    • vus = 30
    • duration = 30s
    • target = URL objetivo
    • maxIter = 5
  2. Persistencia:
    • Guardar configuración en PostgreSQL con un ID único de ejecución.
  3. Loop de ejecución:
    • Ejecutar script de K6 en un contenedor externo.
    • Generar archivo output.json con métricas.
    • Extraer resultados relevantes.
    • Pasar métricas a un nodo IA para evaluar y decidir nuevos parámetros.
    • Guardar resultados y volver al loop.
  4. Finalización:
    • Recuperar todas las iteraciones desde PostgreSQL.
    • Armar tabla con métricas por iteración.
    • Enviar reporte vía correo o cualquier conector de n8n.

Contenedor de ejecución

Para no sobrecargar el worker de n8n, el script de K6 corre en un contenedor externo.

Ejemplo de comando usado dentro del flujo:

sh -lc "mkdir -p /workspace/output && \
VUS='{{ $json.vus }}' \
DURATION='{{ $json.duration }}' \
TARGET='{{ $('Init Params').item.json.target }}' \
k6 run --summary-export /workspace/output/out.json /workspace/k6/script.js"

#.dockerfile

FROM grafana/k6:0.51.0 AS k6base

FROM alpine:3.20

# Herramientas mínimas
RUN apk add --no-cache \
      openssh \
      bash \
      git \
      zip \
      docker-cli \
      shadow \
      curl

# Copiar binario de k6 desde la imagen oficial
COPY --from=k6base /usr/bin/k6 /usr/bin/k6

# Usuario 'runner' (solo dev; en prod usa llaves)
RUN adduser -D -s /bin/bash runner && echo "runner:runner" | chpasswd

# Config SSH: permitir password para 'runner' (dev)
# (en producción usa llaves y desactiva PasswordAuthentication)
RUN sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /etc/ssh/sshd_config && \
    sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/g' /etc/ssh/sshd_config && \
    sed -i 's/^#\?UsePAM.*/UsePAM no/g' /etc/ssh/sshd_config

# Script de arranque: genera host keys y arranca sshd
RUN printf '%s\n' \
  '#!/bin/sh' \
  'set -e' \
  'ssh-keygen -A' \
  'mkdir -p /var/run/sshd' \
  '# (solo dev) dar permisos al socket docker si existe:' \
  '[ -S /var/run/docker.sock ] && chmod 666 /var/run/docker.sock || true' \
  'exec /usr/sbin/sshd -D -e -p 2222' \
  > /usr/local/bin/start-sshd.sh && chmod +x /usr/local/bin/start-sshd.sh

EXPOSE 2222
CMD ["/usr/local/bin/start-sshd.sh"]

# docker-compose.yml

services:
  nodo-ssh:
    build:
      context: .
    container_name: n8n-runner
    environment:
      - TZ=America/Lima
    volumes:
      - ./workspace:/workspace
    ports:
      - "2222:2222"    # SSH
    restart: unless-stopped

Script de K6

El script de K6 se mantiene básico para este POC.
Su objetivo es generar carga contra el TARGET definido en la iteración.

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

export const options = {
  vus: __ENV.VUS ? parseInt(__ENV.VUS) : 10,
  duration: __ENV.DURATION || '60s',
};

export default function () {
  const url = __ENV.TARGET || 'https://test.k6.io';
  const res = http.get(url);
  check(res, { 'status is 200': (r) => r.status === 200 });
  sleep(1);
}

Extracción de métricas

Del archivo output.json se seleccionan variables clave:

  • status → estado general de la ejecución.
  • p95 → percentil 95 de latencia.
  • throughput → número total de requests completados.
  • errorRate → porcentaje de errores.

Ajuste con IA

El nodo de IA recibe las métricas y aplica reglas simples de aceptación:

  • Tiempo de respuesta (p95).
  • Porcentaje de error (errorRate).

Con esos criterios, la IA decide si ajustar los parámetros (vus, duration) o detener el flujo.

Ejemplo de prompt usado:

Persistencia y análisis final

  • Todos los resultados se guardan en PostgreSQL asociados al run_id.
  • Al completar el loop, se consultan todas las iteraciones.
  • Se arma una tabla en HTML

Conclusión

Este POC demostró que n8n puede ser más que un orquestador de integraciones: también puede convertirse en una herramienta útil para automatizar pruebas técnicas en QA. Al integrar K6.io con un motor de IA logramos:

  • Iterar dinámicamente sobre configuraciones de VUs y duraciones.
  • Analizar métricas clave como p95, errorRate y throughput sin intervención manual.
  • Detectar patrones de degradación más rápido.

Aunque este flujo es experimental y tiene limitaciones, abre la puerta a nuevas formas de aplicar IA en escenarios de testing. Próximos pasos podrían incluir:

  • Explorar prompts más optimizados.
  • Conectar resultados a dashboards.
  • Usar datos históricos para predecir puntos de quiebre antes de ejecutar nuevas cargas.

En resumen: automatizar pruebas de rendimiento con n8n + K6.io + IA es posible, escalable y promete ahorrar tiempo valioso en QA.

Próximos pasos:

  • Probar con escenarios de mayor carga.
  • Integrar notificaciones en Slack/Teams.
  • Extender criterios de ajuste (CPU, memoria, logs de error).