Zum Inhalt springen

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.

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:

Der Rest dieser Seite verwendet den API-Client, der in jeder Pipeline ohne Plugin funktioniert.

Speichern Sie zunächst Ihre LoadFocus API-Zugangsdaten sicher in Jenkins:

  1. Navigieren Sie zu Jenkins Dashboard > Manage Jenkins > Manage Credentials
  2. Wählen Sie die entsprechende Credential-Domain (z. B. global)
  3. Klicken Sie auf "Add Credentials"
  4. 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
  5. Wiederholen Sie dies für Ihre Team-ID mit ID: loadfocus-team-id

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()
}
}
}
  1. Erstellen Sie einen neuen Pipeline-Job in Jenkins
  2. Konfigurieren Sie die Pipeline zur Verwendung Ihrer Jenkinsfile
  3. Richten Sie die entsprechende SCM-Konfiguration ein, um Ihr Repository abzurufen

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...
}
}

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'
}
}
}

Erstellen Sie eine Shared Library für wiederverwendbare Performance-Tests:

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
// 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"
}
}
}
}
}
}

Nutzen Sie das Jenkins Performance Plugin, um Testergebnisse zu visualisieren:

  1. Installieren Sie das Performance Plugin in Jenkins
  2. Wandeln Sie die LoadFocus-Ergebnisse in ein vom Plugin unterstütztes Format um (JMeter-CSV oder JUnit-XML)
  3. 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'
}
}

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'
)
}
}
}
}
  1. Timeout-Behandlung: Timeouts für lang laufende Leistungstests festlegen:

    stage('Performance Test') {
    options {
    timeout(time: 60, unit: 'MINUTES')
    }
    steps {
    // Performance test steps
    }
    }
  2. 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
    }
    }
  3. Geplante Tests: Leistungstests nach Zeitplan ausführen:

    pipeline {
    agent any
    triggers {
    cron('0 0 * * *') // Run at midnight every day
    }
    stages {
    // Pipeline stages
    }
    }
  4. Parametrisierte Tests: Testparameter anpassbar machen:

    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 {
    // Run test with parameters
    sh """
    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.