Jenkins
Diese Anleitung zeigt, wie Sie einen LoadFocus-JMeter-Test aus einer Jenkins-Pipeline starten, auf sein Ende warten und den Build fehlschlagen lassen, wenn ein Schwellenwert verfehlt wird. Sie nutzt den LoadFocus API Client (loadfocus-api, über npm installiert). Legen Sie den Test zuerst in LoadFocus an und speichern Sie ihn, siehe So führen Sie einen neuen Apache JMeter-Lasttest durch; die Pipeline startet diesen gespeicherten Test über seinen Namen, daher muss --name der exakte Name Ihres gespeicherten Tests sein.
run-test startet den gespeicherten Test, wartet auf sein Ende und prüft die Schwellenwerte. Wird ein Schwellenwert verfehlt oder schlägt der Lauf fehl, beendet sich der Befehl mit Code 1 und der sh-Schritt schlägt fehl. Schwellenwerte werden für jedes Request-Label einzeln geprüft, und errors ist eine Anzahl fehlgeschlagener Requests, keine Prozentzahl. Ersetzen Sie in den folgenden Beispielen My_JMeter_Test, API_Performance_Test und UI_Performance_Test durch die exakten Namen Ihrer gespeicherten Tests.
Die Ergebnisdatei beginnt mit einigen Fortschrittszeilen vor dem JSON-Objekt, daher kann readJSON file: sie nicht unverändert parsen. Die Beispiele, die die Datei lesen, lesen sie als Text und schneiden sie an der ersten Zeile ab, die nur { enthält. Der Schritt readJSON stammt aus dem Plugin Pipeline Utility Steps.
Jenkins-Plugins
Abschnitt betitelt „Jenkins-Plugins“Wenn Sie lieber einen Build-Schritt als einen Shell-Befehl verwenden, stellt LoadFocus außerdem zwei Jenkins-Plugins bereit. Installieren Sie sie über Manage Jenkins > Plugins:
- JMeter Load Testing in the Cloud for CI/CD by LoadFocus führt Ihre gespeicherten JMeter-Tests aus.
- Load Testing CI/CD Plugin by LoadFocus führt Ihre gespeicherten Cloud-Lasttests (URL) aus.
Der Rest dieser Seite verwendet den API-Client, der in jeder Pipeline ohne Plugin funktioniert.
Einrichtungsschritte
Abschnitt betitelt „Einrichtungsschritte“1. Anmeldedaten in Jenkins speichern
Abschnitt betitelt „1. Anmeldedaten in Jenkins speichern“Speichern Sie zunächst Ihre LoadFocus API-Zugangsdaten sicher in Jenkins:
- Navigieren Sie zu Jenkins Dashboard > Manage Jenkins > Manage Credentials
- Wählen Sie die entsprechende Credential-Domain (z. B. global)
- Klicken Sie auf "Add Credentials"
- Fügen Sie folgende Credentials hinzu:
- Kind: Secret text
- Scope: Global
- Secret: Ihr LoadFocus API-Schlüssel
- ID: loadfocus-api-key
- Description: LoadFocus API Key
- Wiederholen Sie dies für Ihre Team-ID mit ID: loadfocus-team-id
2. Jenkins-Pipeline erstellen
Abschnitt betitelt „2. Jenkins-Pipeline erstellen“Erstellen Sie eine Jenkinsfile in Ihrem Repository:
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 { // Your build steps sh 'npm install' sh 'npm run build' } }
stage('Test') { steps { // Your test steps sh 'npm test' } }
stage('Performance Test') { steps { // Install LoadFocus JMeter API Client sh 'npm install -g @loadfocus/loadfocus-api-client'
// Configure LoadFocus API Client sh 'loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID'
// Performance-Tests ausführen (--name ist der exakte Name eines in LoadFocus gespeicherten Tests) sh ''' loadfocus-api jmeter run-test \ --name "My_JMeter_Test" \ --thresholds "avgresponse<=200,errors==0,p95<=250" \ --format json > performance_results.json '''
// Archive the results archiveArtifacts artifacts: 'performance_results.json', fingerprint: true } }
stage('Deploy') { when { expression { return currentBuild.resultIsBetterOrEqualTo('SUCCESS') } } steps { // Your deployment steps echo 'Deploying...' } } }
post { always { // Clean up workspace cleanWs() } }}3. Jenkins-Job konfigurieren
Abschnitt betitelt „3. Jenkins-Job konfigurieren“- Erstellen Sie einen neuen Pipeline-Job in Jenkins
- Konfigurieren Sie die Pipeline zur Verwendung Ihrer Jenkinsfile
- Richten Sie die entsprechende SCM-Konfiguration ein, um Ihr Repository abzurufen
Erweiterte Konfiguration
Abschnitt betitelt „Erweiterte Konfiguration“Deklarative Pipeline mit parallelen Tests
Abschnitt betitelt „Deklarative Pipeline mit parallelen Tests“Führen Sie mehrere Performance-Tests parallel aus. Ihr LoadFocus-Tarif begrenzt, wie viele Tests gleichzeitig laufen können; darüber meldet der Client "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 { // Previous stages...
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 } } } }
// Next stages... }}Scripted Pipeline
Abschnitt betitelt „Scripted Pipeline“Für mehr Flexibilität nutzen Sie eine Scripted Pipeline. Weil sh fehlschlägt, wenn run-test mit Code 1 endet (ein verfehlter Schwellenwert), läuft der folgende catch-Block bei einem verfehlten Schwellenwert genauso wie bei einem Fehler:
node { def performanceTestPassed = false
stage('Checkout') { checkout scm }
stage('Build & Test') { // Your build and test steps }
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 '''
// Check if test passed by examining the 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!" // Optional: Fail the build // 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...' // Your deployment steps } else { echo 'Skipping deployment due to performance test failure' } }}Shared Library
Abschnitt betitelt „Shared Library“Erstellen Sie eine Shared Library für wiederverwendbare Performance-Tests:
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
// Return the test results def raw = readFile(resultsFile) def testResults = readJSON text: raw.substring(raw.indexOf('\n{') + 1) return testResults } }}Dann in Ihrem 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" } } } } }}Integration mit Jenkins-Plugins
Abschnitt betitelt „Integration mit Jenkins-Plugins“Performance Plugin
Abschnitt betitelt „Performance Plugin“Nutzen Sie das Jenkins Performance Plugin, um Testergebnisse zu visualisieren:
- Installieren Sie das Performance Plugin in Jenkins
- Wandeln Sie die LoadFocus-Ergebnisse in ein vom Plugin unterstütztes Format um (JMeter-CSV oder JUnit-XML)
- Konfigurieren Sie Ihre Pipeline:
stage('Performance Test') { steps { // Run LoadFocus test sh ''' loadfocus-api jmeter run-test \ --name "My_JMeter_Test" \ --thresholds "avgresponse<=200,errors==0,p95<=250" \ --format json > performance_results.json
# Convert to JMeter CSV format (using a custom script) node convert-to-jmeter.js performance_results.json performance_results.csv '''
// Use Performance Plugin perfReport sourceDataFiles: 'performance_results.csv', errorFailedThreshold: 0, errorUnstableThreshold: 0, errorUnstableResponseTimeThreshold: '200' }}E-Mail-Benachrichtigung
Abschnitt betitelt „E-Mail-Benachrichtigung“Senden Sie E-Mail-Benachrichtigungen mit den Testergebnissen:
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}"
// Create email body 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' ) } } }}Tipps für die Jenkins-Integration
Abschnitt betitelt „Tipps für die Jenkins-Integration“-
Timeout-Behandlung: Timeouts für lang laufende Leistungstests festlegen:
stage('Performance Test') {options {timeout(time: 60, unit: 'MINUTES')}steps {// Performance test steps}} -
Bedingte Ausführung: Leistungstests nur auf bestimmten Branches ausführen:
stage('Performance Test') {when {anyOf {branch 'main'branch 'develop'tag pattern: "v\\d+\\.\\d+\\.\\d+", comparator: "REGEXP"}}steps {// Performance test steps}} -
Geplante Tests: Leistungstests nach Zeitplan ausführen:
pipeline {agent anytriggers {cron('0 0 * * *') // Run at midnight every day}stages {// Pipeline stages}} -
Parametrisierte Tests: Testparameter anpassbar machen:
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 {// Run test with parameterssh """loadfocus-api jmeter run-test \\--name "${params.TEST_NAME}" \\--thresholds "${params.THRESHOLDS}" \\--wait-timeout ${params.WAIT_TIMEOUT} \\--format json > performance_results.json"""}}}}
Weitere Informationen finden Sie in der Jenkins-Dokumentation und der LoadFocus API Client-Dokumentation.