GitLab CI/CD
This guide shows how to start a LoadFocus JMeter test from a GitLab CI/CD pipeline, wait for it to finish and fail the pipeline when a threshold is missed. It uses the LoadFocus API Client (loadfocus-api, installed from npm). Create and save the test in LoadFocus first, see How to run a new JMeter load test; the pipeline starts that saved test by name.
Setup Steps
Section titled “Setup Steps”1. Store Credentials as GitLab CI/CD Variables
Section titled “1. Store Credentials as GitLab CI/CD Variables”First, store your LoadFocus API credentials as GitLab CI/CD variables:
-
Go to your GitLab project
-
Navigate to Settings > CI/CD > Variables
-
Add the following variables:
LOADFOCUS_API_KEY: Your LoadFocus API key (mark as "Masked")LOADFOCUS_TEAM_ID: Your LoadFocus team ID
Both are on the API Keys page of your LoadFocus account settings.
2. Create a GitLab CI/CD Pipeline
Section titled “2. Create a GitLab CI/CD Pipeline”Create or update your .gitlab-ci.yml file in your repository:
stages: - build - test - performance - deploy
variables: NODE_VERSION: "20"
build: stage: build image: node:${NODE_VERSION} script: - npm install - npm run build artifacts: paths: - dist/ expire_in: 1 week
test: stage: test image: node:${NODE_VERSION} script: - npm install - npm test
performance_test: stage: performance image: node:${NODE_VERSION} script: # Install LoadFocus JMeter API Client - npm install -g @loadfocus/loadfocus-api-client
# Configure LoadFocus API Client - loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID
# Run Performance Tests. --name is the exact name of a test you saved in LoadFocus. - | loadfocus-api jmeter run-test \ --name "My_JMeter_Test" \ --thresholds "avgresponse<=200,errors==0,p95<=250" \ --format json > performance_results.json artifacts: paths: - performance_results.json expire_in: 1 week when: always # Optional: Only run on specific branches only: - main - develop
deploy: stage: deploy script: - echo "Deploying application..." only: - main # Only deploy if all previous stages succeeded when: on_successrun-test starts the saved test, waits for it to finish and checks the thresholds. If any threshold is missed, or the run fails, the command exits with code 1 and the job fails, so the deploy stage does not run. Thresholds are checked for every request label separately, so one slow request is enough to fail the run. errors is a count of failed requests, not a percentage. In the examples below, replace the GitLab_... names with the exact name of your saved test.
The output file starts with a few progress lines before the JSON object. To get a clean JSON file, keep only the lines from the first line that is just {: sed -n '/^{$/,$p' performance_results.json > results.json.
3. View Test Results
Section titled “3. View Test Results”After the pipeline runs:
- Go to your GitLab project
- Navigate to CI/CD > Pipelines
- Find your pipeline and click on it
- Go to the "performance_test" job
- Click on "Browse" in the right sidebar to view artifacts
- Download and view the
performance_results.jsonfile
Advanced Configuration
Section titled “Advanced Configuration”Environment-specific Testing
Section titled “Environment-specific Testing”Run different performance tests for different environments:
.performance_test_template: &performance_test_definition stage: performance image: node:${NODE_VERSION} script: - npm install -g @loadfocus/loadfocus-api-client - loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID - | loadfocus-api jmeter run-test \ --name "${TEST_NAME}" \ --thresholds "${THRESHOLDS}" \ --format json > performance_results.json artifacts: paths: - performance_results.json expire_in: 1 week when: always
performance_test_develop: <<: *performance_test_definition variables: TEST_NAME: "API_Test_Develop" THRESHOLDS: "avgresponse<=300,errors==0,p95<=500" only: - develop
performance_test_staging: <<: *performance_test_definition variables: TEST_NAME: "API_Test_Staging" THRESHOLDS: "avgresponse<=250,errors==0,p95<=350" only: - staging
performance_test_production: <<: *performance_test_definition variables: TEST_NAME: "API_Test_Production" THRESHOLDS: "avgresponse<=200,errors==0,p95<=250" only: - mainParallel Testing
Section titled “Parallel Testing”Run multiple performance tests in parallel:
performance_test_api: stage: performance image: node:${NODE_VERSION} script: - npm install -g @loadfocus/loadfocus-api-client - loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID - | loadfocus-api jmeter run-test \ --name "API_Performance_Test" \ --thresholds "avgresponse<=150,errors==0" \ --format json > api_performance_results.json artifacts: paths: - api_performance_results.json expire_in: 1 week
performance_test_ui: stage: performance image: node:${NODE_VERSION} script: - npm install -g @loadfocus/loadfocus-api-client - loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID - | loadfocus-api jmeter run-test \ --name "UI_Performance_Test" \ --thresholds "avgresponse<=300,errors==0" \ --format json > ui_performance_results.json artifacts: paths: - ui_performance_results.json expire_in: 1 weekJobs in the same stage run in parallel, and every test they start counts against the parallel-test limit of your plan. To run these tests on a timer instead of on every push, create a pipeline schedule in GitLab:
- Go to your GitLab project
- Navigate to CI/CD > Schedules
- Click "New schedule"
- Set up a schedule (e.g., every day at midnight)
Integration with GitLab Features
Section titled “Integration with GitLab Features”Merge Request Widgets
Section titled “Merge Request Widgets”Display performance test results in merge requests by using GitLab's JUnit report feature:
performance_test: stage: performance image: node:${NODE_VERSION} script: # Run performance test - npm install -g @loadfocus/loadfocus-api-client - loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID - | loadfocus-api jmeter run-test \ --name "GitLab_${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}" \ --thresholds "avgresponse<=200,errors==0,p95<=250" \ --format json > performance_results.json
# Convert to JUnit format (using a custom script) - node convert-to-junit.js performance_results.json junit-report.xml artifacts: reports: junit: junit-report.xml paths: - performance_results.json expire_in: 1 weekGitLab Metrics
Section titled “GitLab Metrics”Use GitLab's metrics feature to track performance over time:
performance_test: stage: performance image: node:${NODE_VERSION} script: # Run performance test - npm install -g @loadfocus/loadfocus-api-client - loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID - | loadfocus-api jmeter run-test \ --name "GitLab_${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}" \ --thresholds "avgresponse<=200,errors==0,p95<=250" \ --format json > performance_results.json
# Extract metrics and report them to GitLab - | # Parse JSON and extract metrics RESPONSE_TIME=$(sed -n '/^{$/,$p' performance_results.json | jq '.labels[0].metrics.avgresponse') ERROR_RATE=$(sed -n '/^{$/,$p' performance_results.json | jq '.labels[0].metrics.errors')
# Report metrics echo "performance_avg_response_time ${RESPONSE_TIME}" >> metrics.txt echo "performance_error_rate ${ERROR_RATE}" >> metrics.txt artifacts: reports: metrics: metrics.txt paths: - performance_results.json expire_in: 1 weekGitLab Environments
Section titled “GitLab Environments”Associate performance tests with specific environments:
performance_test_staging: stage: performance image: node:${NODE_VERSION} environment: name: staging script: - npm install -g @loadfocus/loadfocus-api-client - loadfocus-api config set --apikey $LOADFOCUS_API_KEY --teamid $LOADFOCUS_TEAM_ID - | loadfocus-api jmeter run-test \ --name "Staging_Performance_Test" \ --thresholds "avgresponse<=250,errors==0" \ --format json > performance_results.json artifacts: paths: - performance_results.json expire_in: 1 week only: - stagingTips for GitLab CI/CD Integration
Section titled “Tips for GitLab CI/CD Integration”-
Caching: Cache npm dependencies to speed up pipeline runs:
performance_test:stage: performanceimage: node:${NODE_VERSION}cache:key: ${CI_COMMIT_REF_SLUG}paths:- node_modules/script:- npm install -g @loadfocus/loadfocus-api-client# Rest of the script... -
Timeout Settings: Set timeouts for long-running performance tests:
performance_test:stage: performanceimage: node:${NODE_VERSION}timeout: 2h # Set a 2-hour timeoutscript:# Performance test script... -
Manual Triggers: Allow performance tests to be triggered manually:
performance_test:stage: performanceimage: node:${NODE_VERSION}script:# Performance test script...when: manual -
Dynamic Test Configuration: Use GitLab predefined variables to dynamically configure tests:
performance_test:stage: performanceimage: node:${NODE_VERSION}script:- |# Set thresholds based on branchif [ "$CI_COMMIT_REF_NAME" = "main" ]; thenTHRESHOLDS="avgresponse<=200,errors==0,p95<=250"elseTHRESHOLDS="avgresponse<=300,errors==0,p95<=500"filoadfocus-api jmeter run-test \--name "GitLab_${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}" \--thresholds "$THRESHOLDS" \--format json > performance_results.json -
Notifications: Send notifications when performance tests fail:
performance_test:stage: performanceimage: node:${NODE_VERSION}script:# Performance test script...after_script:- |if [ "$CI_JOB_STATUS" = "failed" ]; then# Send notification using curl, GitLab API, or other methodcurl -X POST -H "Content-Type: application/json" \-d "{\"text\":\"Performance test failed for ${CI_PROJECT_NAME}\"}" \$WEBHOOK_URLfi
For more information, refer to the GitLab CI/CD documentation and the LoadFocus API Client documentation.