Run Performance Test with K6 in Gitlab CI

Irwan Syarifudin
5 min readOct 13, 2024

--

Background

In this tutorial, we will use K6, a popular open-source tool for performance testing, in combination with GitLab CI for continuous testing and integration. This setup allows us to automatically run performance tests during the CI pipeline, generate reports, and notify the team via Slack when a test is completed.

The key objectives of this tutorial are:

  • Run performance tests using K6 within a GitLab CI pipeline.
  • Parse the K6 test results and generate an HTML report.
  • Store test results as artifacts for future reference.
  • Send test summaries to a Slack channel to keep the team informed of performance issues.

By the end of this tutorial, you will have a fully automated pipeline that runs K6 performance tests, reports results, and integrates with your team’s communication tools for real-time feedback.

Setup & Run

To avoid hardcoding sensitive information like the Slack webhook URL, you can store it as an environment variable in GitLab CI.

1. Set the Environment Variable in GitLab

  1. Go to your GitLab repository
  2. Create new webhook for your workspace channel. See this documentation to how to get webhook
  3. Navigate to Settings > CI/CD
  4. Expand the Variables section
  5. Click Add Variable
  6. Set the Key to SLACK_WEBHOOK_URL and Value to your Slack webhook URL (e.g., https://hooks.slack.com/services/xxxxx)
  7. Make sure the Protected and Masked options are enabled (optional but recommended for security)

2. Project Structure

Make sure your directory structure looks like this:

Explanation:

  • performance-test.js: Your K6 performance test script.
  • summary.html: A file to generate an HTML summary report of the K6 test results.
  • parse_results.js: A script to parse K6 results and send a notification to Slack.

3. K6 Script

The K6 script is responsible for defining the load test that will be executed during the GitLab CI pipeline. Here’s a detailed breakdown of how the script works:

import { sleep } from 'k6';
import { htmlReport } from "https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js";
import http from 'k6/http';

export const options = {
duration: '10s',
vus: 10,
thresholds: {
http_req_duration: ['p(95)<500'],
},
};

// The default function defines the user behavior for the load test
export default function () {
http.get('http://test.k6.io/contacts.php');
}

// This function generates an HTML report after the test completes
export function handleSummary(data) {
return {
"summary.html": htmlReport(data),
};
}

4. Custom Function to Send Data to Slack

create cjs file with name parse_result.cjs

const fs = require('fs');
const axios = require('axios');

// use dotenv if you run this script in local and don't forget to npm install dotenv
// require('dotenv').config();

// Read K6 result JSON file
const resultFile = 'results.json';
const slackWebhookUrl = process.env.SLACK_WEBHOOK_URL;

if (!slackWebhookUrl) {
console.error('Slack webhook URL is not set. Exiting...');
process.exit(1);
}

// Read results.json and parse it
fs.readFile(resultFile, 'utf8', (err, data) => {
if (err) {
console.error('Error reading results file:', err);
process.exit(1);
}

const resultData = JSON.parse(data);

// Extract key metrics
const totalRequests = resultData.metrics.http_reqs.count;
const httpReqDurationP95 = resultData.metrics.http_req_duration['p(95)'];
const successRate = (resultData.metrics.http_req_failed.passes / (resultData.metrics.http_req_failed.passes + resultData.metrics.http_req_failed.fails)) * 100;

// Create Slack payload
const slackPayload = {
text: "K6 Load Test Summary",
attachments: [
{
title: "Test Summary",
text: "K6 Load Test Completed. Here are the key metrics:",
fields: [
{
title: "Total Requests",
value: `${totalRequests}`,
short: true
},
{
title: "Request Duration p(95)",
value: `${httpReqDurationP95.toFixed(2)} ms`,
short: true
},
{
title: "Success Rate",
value: `${successRate.toFixed(2)}%`,
short: true
}
]
}
]
};

// Send data to Slack
axios.post(slackWebhookUrl, slackPayload)
.then(response => {
console.log('Successfully sent the summary to Slack.');
})
.catch(error => {
console.error('Error sending summary to Slack:', error);
});
});

This optional if you need test the script in your local, so just create .env file

SLACK_WEBHOOK_URL=https://hooks.slack.com/services/xxxxx

Run script

$ node parse_result.cjs

5. Add Gitlab CI File

Add your GitLab CI configuration to reference the environment variable for the Slack webhook:

stages:
- loadtest

loadtest:
image:
name: grafana/k6:latest
entrypoint: ['']
stage: loadtest
script:
- echo "Executing K6 performance test..."
- k6 run --out json=results.json ./scripts/performance-test.js
- echo "Parsing the results..."
- node parse_results.cjs
artifacts:
paths:
- results.json
- summary.html
expire_in: 1 week
after_script:
- echo "Sending test results to Slack..."
- node parse_results.js

6. Push Your Code and Run

After you push to your gitlab repo, it should be automatically running a pipeline.

Pipeline Execution:

  • Once pushed, GitLab CI/CD will automatically trigger the pipeline based on your .gitlab-ci.yml configuration.
  • Navigate to CI/CD > Pipelines in your GitLab project to monitor the pipeline’s progress.

You can see the pipeline status was running.

Click the pipeline icon to see the detail of job which running

7. Check The Notif Slack

After the pipeline runs successfully, you should receive a notification in your designated Slack channel. As note, ensure that the SLACK_WEBHOOK_URL environment variable is correctly set in GitLab.

8. Check and analysis Test Report from Artifact

GitLab CI/CD allows you to store artifacts generated during the pipeline run. You can access these artifacts to review detailed k6 test reports.

Steps to Access Artifacts:

  1. Go to your GitLab project.
  2. Click on CI/CD > Pipelines.
  3. Click on the most recent pipeline to view its details.
  4. Click on the job to open its details.
  5. Under the Artifacts section, you will see the list of stored files (e.g., result.json, summary.html).
  6. Click on the artifact files to download them.
  7. Open summary.html in a browser to view a detailed HTML report of the k6 test.

Without downloading the artifact first, you can also see directly via your gitlab site with click tab Browse

Then click summary.html

And should the report is as shown in the picture below

By following this tutorial, you have successfully set up automated k6 load testing within a GitLab CI/CD pipeline. You have also integrated Slack notifications to stay informed about your test results and configured artifact storage to review detailed reports.

Benefits:

  • Automated Testing: Ensures that load tests run consistently with every code push.
  • Real-Time Notifications: Keeps your team informed about test outcomes without manual checks.
  • Detailed Reporting: Provides comprehensive insights into performance metrics for further analysis.

🎉 Happy testing!

--

--

Irwan Syarifudin
Irwan Syarifudin

No responses yet