Artillery es un kit de herramientas de prueba de carga de código abierto, basado en Node.js, que dirige tráfico de alta concurrencia a tu API desde un simple script YAML. Defines fases de carga y flujos de solicitud, ejecutas artillery run script.yml, y obtienes percentiles de latencia, tasas de solicitud y recuentos de errores. Esta guía te lleva a través de la instalación de Artillery v2, la escritura de un script de prueba real, su ejecución, la captura de resultados de la manera actual de v2 y su integración en CI.
Qué es Artillery y cuándo usarlo
Artillery genera usuarios virtuales (VUs) que acceden a tus puntos finales y mide cómo el sistema se mantiene bajo un tráfico sostenido. Un usuario virtual es un cliente simulado que ejecuta un escenario, una solicitud tras otra, tal como lo haría un llamador real.
Recurres a Artillery cuando necesitas respuestas a preguntas de escalabilidad. ¿Cómo se comporta la latencia p95 con 50 solicitudes por segundo? ¿A qué tasa de llegada comienzan a aparecer los errores? ¿La API se mantiene estable durante cinco minutos de carga sostenida o se degrada?
Artillery es bueno en esto porque la prueba es declarativa. Describes la forma de la carga en YAML en lugar de codificar manualmente un bucle de concurrencia. Funciona donde sea que se ejecute Node.js, por lo que el mismo script funciona en tu portátil y en CI.
Artillery es una de varias opciones en este espacio. Si aún estás comparando herramientas, el resumen de las principales herramientas de prueba de carga y esta comparación de software de prueba de carga cubren las ventajas y desventajas entre k6, JMeter, Gatling y otros.
Instalar Artillery (v2)
El nombre del paquete es exactamente artillery, y la versión principal actual es v2. Instálalo globalmente con npm, luego verifica la versión.
npm install -g artillery@latest
artillery version
Necesitas una versión LTS reciente de Node.js. Artillery funciona en Windows, macOS y Linux.
Si prefieres no instalar nada globalmente, ejecútalo bajo demanda con npx.
npx artillery@latest run script.yml
Escribiendo un Script de Prueba de Artillery
Una prueba de Artillery es un archivo YAML con dos secciones de nivel superior. La sección config define el objetivo y el perfil de carga. La sección scenarios define lo que hace cada usuario virtual.
Aquí tienes un script completo que calienta, aumenta hasta el pico y luego mantiene una carga sostenida.
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
# Inline variables (or use a CSV via config.payload)
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
Entendiendo la sección config
config.target es el host base contra el que se ejecuta cada solicitud. Cada paso en un escenario añade su url a esta base.
config.phases es un array de fases de carga que se ejecutan en orden. Las claves que más usarás:
duration: cuánto dura la fase, en segundos o una cadena legible por humanos como"5m".arrivalRate: cuántos nuevos usuarios virtuales inician cada segundo.rampTo: aumenta linealmente la tasa de llegada desdearrivalRatehasta este valor a lo largo de la fase.arrivalCount: un número fijo de VUs distribuidos a lo largo de la fase, en lugar de una tasa por segundo.maxVusers: un límite de cuántos usuarios virtuales pueden ejecutarse concurrentemente.name: una etiqueta que aparece en la salida.
Un detalle que confunde a la gente. La duration de una fase controla cuánto tiempo Artillery sigue generando usuarios virtuales, no el tiempo total de reloj de la prueba. Si un VU comienza cerca del final de una fase y su escenario tarda un tiempo, la ejecución continúa hasta que ese usuario termina.
Entendiendo la sección scenarios
scenarios es un array. Cada escenario tiene un flow, que es la lista ordenada de pasos que ejecuta un usuario virtual. Las claves opcionales incluyen name y weight, donde weight establece la probabilidad relativa de que Artillery elija este escenario para un VU dado.
Los pasos de flujo utilizan claves de verbos HTTP: get, post, put, delete y patch. Cada uno toma una url, y los cuerpos de solicitud van bajo json. La sintaxis de doble corchete, {{ productId }}, extrae una variable.
Dirigiendo solicitudes desde un archivo CSV
Codificar valores directamente está bien para una prueba de humo. Para una carga realista, alimenta datos desde un CSV con config.payload. Cada usuario virtual elige una fila, y los nombres de las columnas se convierten en variables.
config:
target: "https://api.example.com"
payload:
path: "./users.csv"
fields:
- "email"
- "password"
phases:
- duration: 120
arrivalRate: 20
scenarios:
- flow:
- post:
url: "/login"
json:
email: "{{ email }}"
password: "{{ password }}"
Ejecutando la Prueba
El comando básico apunta Artillery a tu script.
artillery run script.yml
# Override target without editing the script:
artillery run --target https://staging.example.com script.yml
# Pass variables as JSON:
artillery run -v '{ "productId": ["1001","1002"] }' script.yml
Vale la pena conocer algunas banderas. --target (o -t) anula config.target para que puedas apuntar el mismo script a staging o producción. --environment (o -e) selecciona un bloque nombrado bajo config.environments. --config (o -c) carga la configuración desde un archivo separado. --insecure (o -k) omite la verificación TLS para certificados autofirmados en entornos de prueba.
Leyendo los Resultados
Mientras la prueba se ejecuta, Artillery imprime métricas agregadas aproximadamente cada 10 segundos. Cuando termina, obtienes un informe de resumen. Los números que más importan:
- Tasa de solicitudes: solicitudes por segundo que la ejecución realmente logró.
- Percentiles de latencia: tiempos de respuesta p50 (mediana), p95 y p99. El p95 te indica la experiencia del 5 por ciento más lento de las solicitudes, que suele ser donde aparecen primero los problemas.
- Recuentos de errores: solicitudes fallidas, tiempos de espera y respuestas que no son 2xx, agrupadas por tipo.
Observa las latencias de cola, no solo el promedio. Un promedio puede parecer saludable mientras que el p99 sube silenciosamente a territorio de varios segundos. Si los errores aparecen solo durante la fase sostenida, es probable que hayas encontrado un punto de saturación que vale la pena investigar. Para un tratamiento más profundo de qué métricas rastrear y por qué, consulta esta guía de pruebas de rendimiento de API.
Generando un Informe en Artillery v2
La generación de informes cambió entre las versiones de Artillery, por lo que aquí es donde los tutoriales desactualizados te desvían. Las guías antiguas te dicen que ejecutes artillery run --output report.json y luego artillery report report.json para producir un archivo HTML. La primera parte todavía funciona. La segunda parte no.
La bandera --output aún escribe un archivo de resultados JSON legible por máquina.
# Escribe resultados JSON legibles por máquina (aún soportado):
artillery run --output report.json script.yml
El comando artillery report, el generador de JSON a HTML, ha sido eliminado de la CLI de Artillery. La documentación oficial establece que «ya no es compatible y ha sido eliminado de la CLI de Artillery». El código de informes HTML quedó sin mantenimiento, fue obsoleto y luego se eliminó, sin planes de recuperarlo. No escribas artillery report report.json; no funcionará en la v2 actual.
Tienes tres opciones actuales en su lugar.
Primero, analiza el JSON tú mismo. Esto es ideal para CI, donde quieres afirmar contra un umbral. Obtén la latencia p95 agregada con jq:
jq '.aggregate.summaries["http.response_time"].p95' report.json
Segundo, usa Artillery Cloud para un panel de control alojado. Este es el reemplazo oficial del antiguo informe HTML. Pasa --record con tu clave de API.
artillery run --record --key $ARTILLERY_CLOUD_API_KEY script.yml
Tercero, envía métricas a tu propia pila de monitoreo con el plugin publish-metrics o OpenTelemetry, para que las tasas de latencia y error aparezcan en los mismos paneles que ya usas para producción.
Ejecutando Artillery en CI
Dado que Artillery es solo una CLI de Node.js, se integra en cualquier pipeline. Aquí tienes un flujo de trabajo de GitHub Actions que instala Artillery, ejecuta la prueba y sube el informe JSON como un artefacto de compilación.
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
Este ejemplo se ejecuta mediante activación manual. Las pruebas de carga pesadas suelen activarse bajo demanda o según un cronograma, en lugar de con cada commit, ya que tardan minutos y consumen ancho de banda real. Una vez que existe el informe JSON, puedes añadir un paso de jq que falle el trabajo si el p95 excede tu presupuesto.
Dónde Encaja Apidog: Pruebas Funcionales y Control de CI
Artillery responde a la pregunta “¿puede la API sobrevivir a tanto tráfico?”. Eso es prueba de carga y rendimiento. Una pregunta diferente que corre en paralelo es: “¿la API sigue devolviendo respuestas correctas después de este cambio de código?”. Eso es prueba funcional y de regresión, y es donde encaja Apidog.
Apidog es una plataforma API todo en uno para diseño, depuración, mocking, documentación y pruebas automatizadas. Sus escenarios de prueba agrupan puntos finales en pasos lógicos con condiciones como if, for y foreach, para que puedas validar cuerpos de respuesta, códigos de estado y contratos. Ejecutas esos escenarios en CI con la CLI de Apidog para controlar las fusiones después de los cambios de código.
Sé claro sobre el límite. Apidog incluye una función de prueba de rendimiento, pero está limitada a un máximo de 100 usuarios virtuales. Eso es suficiente para detectar regresiones obvias, y no es un sustituto de Artillery en alta concurrencia. Para cargas distribuidas y modeladas por código a gran escala, Artillery es la herramienta adecuada. Esta misma honesta contextualización aparece en nuestro artículo sobre pruebas de carga de APIs sin Python, y la mecánica de la función de 100 VUs de Apidog se cubre en pruebas de rendimiento de API en Apidog.
Así que usa ambos. Realiza pruebas de carga con Artillery para escalar. Ejecuta verificaciones funcionales y de regresión en CI con la CLI de Apidog para detectar comportamientos rotos antes de que se implementen.
La CLI de Apidog se instala desde npm, y apidog run solo admite banderas.
# Apidog CLI: functional/regression run in CI (flag-only, no positional file)
npm install -g apidog-cli
apidog run \
--access-token $APIDOG_ACCESS_TOKEN \
-t <TEST_SCENARIO_ID> \
-e <ENVIRONMENT_ID> \
-r cli,junit \
--out-dir ./apidog-reports
La bandera -t es el ID del escenario de prueba, -e es el ID de entorno requerido, y -r cli,junit emite tanto la salida de consola como un informe JUnit XML que los sistemas CI pueden leer. Para un tutorial paso a paso, consulta el tutorial de la CLI de Apidog, y para patrones de diseño de pipelines, consulta estas mejores prácticas de CI/CD para pruebas de API.
¿Quieres pruebas funcionales y de contrato controlando tu CI junto con tus ejecuciones de carga de Artillery? Descarga Apidog gratis y construye tu primer escenario de prueba.
Preguntas Frecuentes
¿Qué es la prueba de carga con Artillery?
La prueba de carga con Artillery es la práctica de usar el kit de herramientas de código abierto Artillery para simular muchos usuarios virtuales concurrentes accediendo a tu API. Describes la forma de la carga y el flujo de solicitudes en un script YAML, lo ejecutas y mides percentiles de latencia, tasas de solicitud y errores para ver cómo se comporta tu sistema bajo estrés.
¿Es Artillery gratuito y de código abierto?
Sí. La CLI central de Artillery es gratuita y de código abierto, distribuida en npm como el paquete artillery. También hay una oferta de pago alojada, Artillery Cloud, que proporciona un panel para los resultados, pero puedes ejecutar pruebas de carga completas localmente y en CI sin ella.
¿Cómo se ejecuta una prueba de carga con Artillery?
Instálalo con npm install -g artillery@latest, escribe un script YAML con un bloque config (objetivo y fases) y un bloque scenarios (el flujo de solicitudes), luego ejecuta artillery run script.yml. Artillery imprime métricas en vivo cada 10 segundos y un resumen al final.
¿Cómo se genera un informe de Artillery?
Ejecuta artillery run --output report.json script.yml para escribir un archivo de resultados JSON. El antiguo comando artillery report que producía HTML ha sido eliminado de la CLI. En su lugar, analiza el JSON con una herramienta como jq, usa Artillery Cloud a través de `--record --key`, o envía métricas con el plugin publish-metrics u OpenTelemetry.
Artillery vs k6 o JMeter: ¿cuál deberías usar?
Los tres manejan cargas a gran escala. Artillery usa YAML declarativo y Node.js, lo que se adapta a equipos ya en el ecosistema JavaScript. k6 escribe scripts en JavaScript con un modelo code-first. JMeter es impulsado por GUI y basado en Java con una larga historia de plugins. La comparación Gatling vs JMeter cubre las ventajas y desventajas con mayor profundidad. Elige el que su modelo de scripting coincida con tu equipo, luego combínalo con pruebas funcionales de CI para una cobertura completa.
