Jenkins
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.
Plugins de Jenkins
Sección titulada «Plugins de Jenkins»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:
- JMeter Load Testing in the Cloud for CI/CD by LoadFocus ejecuta tus pruebas JMeter guardadas.
- Load Testing CI/CD Plugin by LoadFocus ejecuta tus pruebas de carga cloud (URL) guardadas.
El resto de esta página usa el cliente de la API, que funciona en cualquier pipeline sin instalar ningún plugin.
Pasos de Configuración
Sección titulada «Pasos de Configuración»1. Almacenar Credenciales en Jenkins
Sección titulada «1. Almacenar Credenciales en Jenkins»Primero, almacena tus credenciales de API de LoadFocus de forma segura en Jenkins:
- Navega a Jenkins Dashboard > Manage Jenkins > Manage Credentials
- Selecciona el dominio de credenciales apropiado (por ejemplo, global)
- Haz clic en "Add Credentials"
- Agrega las siguientes credenciales:
- Kind: Secret text
- Scope: Global
- Secret: Tu clave API de LoadFocus
- ID: loadfocus-api-key
- Description: LoadFocus API Key
- Repite el proceso para tu ID de equipo con ID: loadfocus-team-id
2. Crear un Pipeline de Jenkins
Sección titulada «2. Crear un Pipeline de Jenkins»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() } }}3. Configurar el Job de Jenkins
Sección titulada «3. Configurar el Job de Jenkins»- Crea un nuevo job de Pipeline en Jenkins
- Configura el Pipeline para usar tu Jenkinsfile
- Configura la configuración SCM apropiada para obtener tu repositorio
Configuración Avanzada
Sección titulada «Configuración Avanzada»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... }}Pipeline con Script
Sección titulada «Pipeline con Script»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' } }}Biblioteca Compartida
Sección titulada «Biblioteca Compartida»Crea una biblioteca compartida para pruebas de rendimiento reutilizables:
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" } } } } }}Integración con Plugins de Jenkins
Sección titulada «Integración con Plugins de Jenkins»Plugin de Rendimiento
Sección titulada «Plugin de Rendimiento»Usa el Plugin de Rendimiento de Jenkins para visualizar los resultados de las pruebas:
- Instala el Plugin de Rendimiento en Jenkins
- Convierte los resultados de LoadFocus a un formato compatible con el plugin (CSV de JMeter o XML de JUnit)
- 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' }}Notificación por Correo Electrónico
Sección titulada «Notificación por Correo Electrónico»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' ) } } }}Consejos para la Integración con Jenkins
Sección titulada «Consejos para la Integración con Jenkins»-
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}} -
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}} -
Pruebas Programadas: Ejecuta pruebas de rendimiento según un horario:
pipeline {agent anytriggers {cron('0 0 * * *') // Ejecutar a medianoche todos los días}stages {// Etapas del pipeline}} -
Pruebas Parametrizadas: Permite la personalización de parámetros de prueba:
pipeline {agent anyparameters {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ámetrossh """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.