Ir al contenido

Esta guía muestra cómo iniciar una prueba JMeter de LoadFocus desde un pipeline de Jenkins, esperar a que termine y hacer fallar el build cuando no se cumple un umbral. Usa el LoadFocus API Client (loadfocus-api, instalado desde npm). Primero crea y guarda la prueba en LoadFocus, consulta Cómo ejecutar una nueva prueba de carga con Apache JMeter; el pipeline inicia esa prueba guardada por su nombre, así que --name debe ser el nombre exacto de tu prueba guardada.

run-test inicia la prueba guardada, espera a que termine y comprueba los umbrales. Si no se cumple algún umbral, o la ejecución falla, el comando termina con código 1 y el paso sh falla. Los umbrales se comprueban para cada etiqueta de petición por separado, y errors es un recuento de peticiones fallidas, no un porcentaje. En los ejemplos siguientes, sustituye My_JMeter_Test, API_Performance_Test y UI_Performance_Test por los nombres exactos de tus pruebas guardadas.

El archivo de resultados empieza con algunas líneas de progreso antes del objeto JSON, así que readJSON file: no puede analizarlo tal cual. Los ejemplos que leen el archivo lo leen como texto y lo cortan en la primera línea que contiene únicamente {. El paso readJSON proviene del plugin Pipeline Utility Steps.

Si prefieres un paso de compilación en lugar de un comando de shell, LoadFocus también publica dos plugins de Jenkins. Instálalos desde Manage Jenkins > Plugins:

El resto de esta página usa el cliente de la API, que funciona en cualquier pipeline sin instalar ningún plugin.

Primero, almacena tus credenciales de API de LoadFocus de forma segura en Jenkins:

  1. Navega a Jenkins Dashboard > Manage Jenkins > Manage Credentials
  2. Selecciona el dominio de credenciales apropiado (por ejemplo, global)
  3. Haz clic en "Add Credentials"
  4. Agrega las siguientes credenciales:
    • Kind: Secret text
    • Scope: Global
    • Secret: Tu clave API de LoadFocus
    • ID: loadfocus-api-key
    • Description: LoadFocus API Key
  5. Repite el proceso para tu ID de equipo con ID: loadfocus-team-id

Crea un Jenkinsfile en tu repositorio:

pipeline {
agent {
docker {
image 'node:16-alpine'
}
}
environment {
LOADFOCUS_API_KEY = credentials('loadfocus-api-key')
LOADFOCUS_TEAM_ID = credentials('loadfocus-team-id')
}
stages {
stage('Build') {
steps {
// Tus pasos de compilación
sh 'npm install'
sh 'npm run build'
}
}
stage('Test') {
steps {
// Tus pasos de prueba
sh 'npm test'
}
}
stage('Performance Test') {
steps {
// Instalar Cliente API de JMeter de LoadFocus
sh 'npm install -g @loadfocus/loadfocus-api-client'
// Configurar Cliente API de LoadFocus
sh 'loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID'
// Ejecutar pruebas de rendimiento (--name es el nombre exacto de una prueba guardada en LoadFocus)
sh '''
loadfocus-api jmeter run-test \
--name "My_JMeter_Test" \
--thresholds "avgresponse<=200,errors==0,p95<=250" \
--format json > performance_results.json
'''
// Archivar los resultados
archiveArtifacts artifacts: 'performance_results.json', fingerprint: true
}
}
stage('Deploy') {
when {
expression {
return currentBuild.resultIsBetterOrEqualTo('SUCCESS')
}
}
steps {
// Tus pasos de despliegue
echo 'Deploying...'
}
}
}
post {
always {
// Limpiar espacio de trabajo
cleanWs()
}
}
}
  1. Crea un nuevo job de Pipeline en Jenkins
  2. Configura el Pipeline para usar tu Jenkinsfile
  3. Configura la configuración SCM apropiada para obtener tu repositorio

Pipeline Declarativo con Pruebas en Paralelo

Sección titulada «Pipeline Declarativo con Pruebas en Paralelo»

Ejecuta varias pruebas de rendimiento en paralelo. Tu plan de LoadFocus limita cuántas pruebas pueden ejecutarse a la vez; por encima de ese límite el cliente informa "Maximum number of parallel tests exceeded for your plan.":

pipeline {
agent any
environment {
LOADFOCUS_API_KEY = credentials('loadfocus-api-key')
LOADFOCUS_TEAM_ID = credentials('loadfocus-team-id')
}
stages {
// Etapas anteriores...
stage('Performance Tests') {
parallel {
stage('API Performance') {
agent {
docker {
image 'node:16-alpine'
}
}
steps {
sh 'npm install -g @loadfocus/loadfocus-api-client'
sh 'loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID'
sh '''
loadfocus-api jmeter run-test \
--name "API_Performance_Test" \
--thresholds "avgresponse<=150,errors==0" \
--format json > api_performance_results.json
'''
archiveArtifacts artifacts: 'api_performance_results.json', fingerprint: true
}
}
stage('UI Performance') {
agent {
docker {
image 'node:16-alpine'
}
}
steps {
sh 'npm install -g @loadfocus/loadfocus-api-client'
sh 'loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID'
sh '''
loadfocus-api jmeter run-test \
--name "UI_Performance_Test" \
--thresholds "avgresponse<=300,errors==0" \
--format json > ui_performance_results.json
'''
archiveArtifacts artifacts: 'ui_performance_results.json', fingerprint: true
}
}
}
}
// Siguientes etapas...
}
}

Para más flexibilidad, usa un pipeline con script (scripted pipeline). Como sh falla cuando run-test termina con código 1 (un umbral incumplido), el bloque catch de abajo se ejecuta tanto por un umbral incumplido como por un error:

node {
def performanceTestPassed = false
stage('Checkout') {
checkout scm
}
stage('Build & Test') {
// Tus pasos de compilación y prueba
}
stage('Performance Test') {
docker.image('node:16-alpine').inside {
withCredentials([
string(credentialsId: 'loadfocus-api-key', variable: 'LOADFOCUS_API_KEY'),
string(credentialsId: 'loadfocus-team-id', variable: 'LOADFOCUS_TEAM_ID')
]) {
sh 'npm install -g @loadfocus/loadfocus-api-client'
sh 'loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID'
try {
sh '''
loadfocus-api jmeter run-test \
--name "My_JMeter_Test" \
--thresholds "avgresponse<=200,errors==0,p95<=250" \
--format json > performance_results.json
'''
// Verificar si la prueba pasó examinando el JSON
def raw = readFile('performance_results.json')
def testResults = readJSON text: raw.substring(raw.indexOf('\n{') + 1)
if (testResults.overallResult == 'PASSED') {
performanceTestPassed = true
echo "Performance test passed!"
} else {
echo "Performance test failed to meet thresholds!"
// Opcional: Fallar la compilación
// error "Performance test failed"
}
} catch (Exception e) {
echo "Error running performance test: ${e.message}"
}
archiveArtifacts artifacts: 'performance_results.json', fingerprint: true
}
}
}
stage('Deploy') {
if (performanceTestPassed) {
echo 'Deploying...'
// Tus pasos de despliegue
} else {
echo 'Skipping deployment due to performance test failure'
}
}
}

Crea una biblioteca compartida para pruebas de rendimiento reutilizables:

vars/performanceTest.groovy
def call(Map config = [:]) {
def testName = config.testName ?: "My_JMeter_Test"
def thresholds = config.thresholds ?: "avgresponse<=200,errors==0,p95<=250"
def waitTimeout = config.waitTimeout ?: 1800
def resultsFile = config.resultsFile ?: "performance_results.json"
docker.image('node:16-alpine').inside {
withCredentials([
string(credentialsId: 'loadfocus-api-key', variable: 'LOADFOCUS_API_KEY'),
string(credentialsId: 'loadfocus-team-id', variable: 'LOADFOCUS_TEAM_ID')
]) {
sh 'npm install -g @loadfocus/loadfocus-api-client'
sh 'loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID'
sh """
loadfocus-api jmeter run-test \\
--name "${testName}" \\
--thresholds "${thresholds}" \\
--wait-timeout ${waitTimeout} \\
--format json > ${resultsFile}
"""
archiveArtifacts artifacts: resultsFile, fingerprint: true
// Devolver los resultados de la prueba
def raw = readFile(resultsFile)
def testResults = readJSON text: raw.substring(raw.indexOf('\n{') + 1)
return testResults
}
}
}

Luego en tu Jenkinsfile:

@Library('my-shared-library') _
pipeline {
agent any
stages {
stage('Performance Test') {
steps {
script {
def results = performanceTest(
testName: "API_Performance_Test",
thresholds: "avgresponse<=150,errors==0"
)
if (results.overallResult != 'PASSED') {
error "Performance test failed"
}
}
}
}
}
}

Usa el Plugin de Rendimiento de Jenkins para visualizar los resultados de las pruebas:

  1. Instala el Plugin de Rendimiento en Jenkins
  2. Convierte los resultados de LoadFocus a un formato compatible con el plugin (CSV de JMeter o XML de JUnit)
  3. Configura tu pipeline:
stage('Performance Test') {
steps {
// Ejecutar prueba de LoadFocus
sh '''
loadfocus-api jmeter run-test \
--name "My_JMeter_Test" \
--thresholds "avgresponse<=200,errors==0,p95<=250" \
--format json > performance_results.json
# Convertir a formato CSV de JMeter (usando un script personalizado)
node convert-to-jmeter.js performance_results.json performance_results.csv
'''
// Usar Plugin de Rendimiento
perfReport sourceDataFiles: 'performance_results.csv',
errorFailedThreshold: 0,
errorUnstableThreshold: 0,
errorUnstableResponseTimeThreshold: '200'
}
}

Envía notificaciones por correo electrónico con los resultados de las pruebas:

post {
always {
script {
if (fileExists('performance_results.json')) {
def raw = readFile('performance_results.json')
def results = readJSON text: raw.substring(raw.indexOf('\n{') + 1)
def resultStatus = results.overallResult == 'PASSED' ? 'SUCCESS' : 'FAILURE'
def subject = "Performance Test ${resultStatus}: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
// Crear cuerpo del correo
def body = """
<h2>Performance Test Results</h2>
<p><strong>Overall Result:</strong> ${results.overallResult}</p>
<h3>Results by Label</h3>
<table border="1">
<tr><th>Label</th><th>Result</th><th>Avg Response</th><th>Errors</th></tr>
"""
results.labels.each { label ->
body += """
<tr>
<td>${label.label}</td>
<td>${label.result}</td>
<td>${label.metrics.avgresponse}ms</td>
<td>${label.metrics.errors}</td>
</tr>
"""
}
body += "</table>"
emailext (
subject: subject,
body: body,
to: 'team@example.com',
attachmentsPattern: 'performance_results.json',
mimeType: 'text/html'
)
}
}
}
}
  1. Manejo de Tiempo de Espera: Establece tiempos de espera para pruebas de rendimiento de larga duración:

    stage('Performance Test') {
    options {
    timeout(time: 60, unit: 'MINUTES')
    }
    steps {
    // Pasos de prueba de rendimiento
    }
    }
  2. Ejecución Condicional: Ejecuta pruebas de rendimiento solo en ramas específicas:

    stage('Performance Test') {
    when {
    anyOf {
    branch 'main'
    branch 'develop'
    tag pattern: "v\\d+\\.\\d+\\.\\d+", comparator: "REGEXP"
    }
    }
    steps {
    // Pasos de prueba de rendimiento
    }
    }
  3. Pruebas Programadas: Ejecuta pruebas de rendimiento según un horario:

    pipeline {
    agent any
    triggers {
    cron('0 0 * * *') // Ejecutar a medianoche todos los días
    }
    stages {
    // Etapas del pipeline
    }
    }
  4. Pruebas Parametrizadas: Permite la personalización de parámetros de prueba:

    pipeline {
    agent any
    parameters {
    string(name: 'TEST_NAME', defaultValue: 'API_Performance_Test', description: 'Name of the LoadFocus test to run')
    string(name: 'THRESHOLDS', defaultValue: 'avgresponse<=200,errors==0', description: 'Performance thresholds')
    string(name: 'WAIT_TIMEOUT', defaultValue: '1800', description: 'Maximum wait time in seconds')
    }
    stages {
    stage('Performance Test') {
    steps {
    // Ejecutar prueba con parámetros
    sh """
    loadfocus-api jmeter run-test \\
    --name "${params.TEST_NAME}" \\
    --thresholds "${params.THRESHOLDS}" \\
    --wait-timeout ${params.WAIT_TIMEOUT} \\
    --format json > performance_results.json
    """
    }
    }
    }
    }

Para más información, consulta la documentación de Jenkins y la documentación del Cliente API de LoadFocus.