Jenkins

이 가이드에서는 자동화된 성능 테스트를 위해 LoadFocus JMeter API Client를 Jenkins와 통합하는 방법을 설명합니다.

설정 단계

1. Jenkins에 자격 증명 저장

먼저 LoadFocus API 자격 증명을 Jenkins에 안전하게 저장합니다:

  1. Jenkins 대시보드 > Manage Jenkins > Manage Credentials로 이동합니다
  2. 적절한 자격 증명 도메인(예: global)을 선택합니다
  3. "Add Credentials"를 클릭합니다
  4. 다음 자격 증명을 추가합니다:
    • Kind: Secret text
    • Scope: Global
    • Secret: LoadFocus API 키
    • ID: loadfocus-api-key
    • Description: LoadFocus API Key
  5. 팀 ID에 대해 ID: loadfocus-team-id로 반복합니다

2. Jenkins 파이프라인 생성

리포지토리에 Jenkinsfile을 생성합니다:

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 {
// 빌드 단계
sh 'npm install'
sh 'npm run build'
}
}
stage('Test') {
steps {
// 테스트 단계
sh 'npm test'
}
}
stage('Performance Test') {
steps {
// LoadFocus JMeter API Client 설치
sh 'npm install -g @loadfocus/loadfocus-api-client'
// LoadFocus API Client 구성
sh 'loadfocus-api config set apikey $LOADFOCUS_API_KEY'
sh 'loadfocus-api config set teamid $LOADFOCUS_TEAM_ID'
// 성능 테스트 실행
sh '''
loadfocus-api jmeter run-test \
--name "Jenkins_${JOB_NAME}_${BUILD_NUMBER}" \
--thresholds "avgresponse<=200,errors==0,p95<=250" \
--format json > performance_results.json
'''
// 결과 아카이브
archiveArtifacts artifacts: 'performance_results.json', fingerprint: true
}
}
stage('Deploy') {
when {
expression {
return currentBuild.resultIsBetterOrEqualTo('SUCCESS')
}
}
steps {
// 배포 단계
echo 'Deploying...'
}
}
}
post {
always {
// 워크스페이스 정리
cleanWs()
}
}
}

3. Jenkins 작업 구성

  1. Jenkins에서 새 Pipeline 작업을 생성합니다
  2. Jenkinsfile을 사용하도록 Pipeline을 구성합니다
  3. 리포지토리를 가져오기 위한 적절한 SCM 구성을 설정합니다

고급 구성

병렬 테스트가 포함된 선언적 파이프라인

여러 성능 테스트를 병렬로 실행합니다:

pipeline {
agent any
environment {
LOADFOCUS_API_KEY = credentials('loadfocus-api-key')
LOADFOCUS_TEAM_ID = credentials('loadfocus-team-id')
}
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'
sh 'loadfocus-api config set 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'
sh 'loadfocus-api config set 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
}
}
}
}
// 다음 스테이지...
}
}

스크립트 파이프라인

더 많은 유연성을 위해 스크립트 파이프라인을 사용합니다:

node {
def performanceTestPassed = false
stage('Checkout') {
checkout scm
}
stage('Build & Test') {
// 빌드 및 테스트 단계
}
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'
sh 'loadfocus-api config set teamid $LOADFOCUS_TEAM_ID'
try {
sh '''
loadfocus-api jmeter run-test \
--name "Jenkins_${JOB_NAME}_${BUILD_NUMBER}" \
--thresholds "avgresponse<=200,errors==0,p95<=250" \
--format json > performance_results.json
'''
// JSON을 검사하여 테스트 통과 여부 확인
def testResults = readJSON file: 'performance_results.json'
if (testResults.overallResult == 'PASSED') {
performanceTestPassed = true
echo "성능 테스트 통과!"
} else {
echo "성능 테스트가 임계값을 충족하지 못했습니다!"
// 선택 사항: 빌드 실패 처리
// error "성능 테스트 실패"
}
} catch (Exception e) {
echo "성능 테스트 실행 오류: ${e.message}"
}
archiveArtifacts artifacts: 'performance_results.json', fingerprint: true
}
}
}
stage('Deploy') {
if (performanceTestPassed) {
echo '배포 중...'
// 배포 단계
} else {
echo '성능 테스트 실패로 인해 배포를 건너뜁니다'
}
}
}

공유 라이브러리

재사용 가능한 성능 테스트를 위한 공유 라이브러리를 생성합니다:

// vars/performanceTest.groovy
def call(Map config = [:]) {
def testName = config.testName ?: "Jenkins_${env.JOB_NAME}_${env.BUILD_NUMBER}"
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'
sh 'loadfocus-api config set teamid $LOADFOCUS_TEAM_ID'
sh """
loadfocus-api jmeter run-test \\
--name "${testName}" \\
--thresholds "${thresholds}" \\
--waitTimeout ${waitTimeout} \\
--format json > ${resultsFile}
"""
archiveArtifacts artifacts: resultsFile, fingerprint: true
// 테스트 결과 반환
def testResults = readJSON file: resultsFile
return testResults
}
}
}

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 "성능 테스트 실패"
}
}
}
}
}
}

Jenkins 플러그인과의 통합

Performance 플러그인

Jenkins Performance 플러그인을 사용하여 테스트 결과를 시각화합니다:

  1. Jenkins에 Performance 플러그인을 설치합니다
  2. LoadFocus 결과를 플러그인에서 지원하는 형식(JMeter CSV 또는 JUnit XML)으로 변환합니다
  3. 파이프라인을 구성합니다:
stage('Performance Test') {
steps {
// LoadFocus 테스트 실행
sh '''
loadfocus-api jmeter run-test \
--name "Jenkins_${JOB_NAME}_${BUILD_NUMBER}" \
--thresholds "avgresponse<=200,errors==0,p95<=250" \
--format json > performance_results.json
# JMeter CSV 형식으로 변환 (커스텀 스크립트 사용)
node convert-to-jmeter.js performance_results.json performance_results.csv
'''
// Performance 플러그인 사용
perfReport sourceDataFiles: 'performance_results.csv',
errorFailedThreshold: 0,
errorUnstableThreshold: 0,
errorUnstableResponseTimeThreshold: '200'
}
}

이메일 알림

테스트 결과와 함께 이메일 알림을 보냅니다:

post {
always {
script {
if (fileExists('performance_results.json')) {
def results = readJSON file: 'performance_results.json'
def resultStatus = results.overallResult == 'PASSED' ? 'SUCCESS' : 'FAILURE'
def subject = "Performance Test ${resultStatus}: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
// 이메일 본문 작성
def body = """
<h2>성능 테스트 결과</h2>
<p><strong>전체 결과:</strong> ${results.overallResult}</p>
<h3>레이블별 결과</h3>
<table border="1">
<tr><th>레이블</th><th>결과</th><th>평균 응답</th><th>오류</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'
)
}
}
}
}

Jenkins 통합 팁

  1. 타임아웃 처리: 오래 실행되는 성능 테스트에 대한 타임아웃을 설정합니다:

    stage('Performance Test') {
    options {
    timeout(time: 60, unit: 'MINUTES')
    }
    steps {
    // 성능 테스트 단계
    }
    }
  2. 조건부 실행: 특정 브랜치에서만 성능 테스트를 실행합니다:

    stage('Performance Test') {
    when {
    anyOf {
    branch 'main'
    branch 'develop'
    tag pattern: "v\\d+\\.\\d+\\.\\d+", comparator: "REGEXP"
    }
    }
    steps {
    // 성능 테스트 단계
    }
    }
  3. 예약 테스트: 일정에 따라 성능 테스트를 실행합니다:

    pipeline {
    agent any
    triggers {
    cron('0 0 * * *') // 매일 자정에 실행
    }
    stages {
    // 파이프라인 스테이지
    }
    }
  4. 파라미터화된 테스트: 테스트 파라미터의 사용자 정의를 허용합니다:

    pipeline {
    agent any
    parameters {
    string(name: 'TEST_NAME', defaultValue: 'API_Performance_Test', description: '실행할 LoadFocus 테스트 이름')
    string(name: 'THRESHOLDS', defaultValue: 'avgresponse<=200,errors==0', description: '성능 임계값')
    string(name: 'WAIT_TIMEOUT', defaultValue: '1800', description: '최대 대기 시간(초)')
    }
    stages {
    stage('Performance Test') {
    steps {
    // 파라미터로 테스트 실행
    sh """
    loadfocus-api jmeter run-test \\
    --name "${params.TEST_NAME}" \\
    --thresholds "${params.THRESHOLDS}" \\
    --waitTimeout ${params.WAIT_TIMEOUT} \\
    --format json > performance_results.json
    """
    }
    }
    }
    }

자세한 정보는 Jenkins 문서LoadFocus API Client 문서를 참조하세요.