- Published on
k6
- Authors
- Name
- PatharaNor
Introduction
k6
is a developer-centric, free and open-source load testing tool built for making performance testing a productive and enjoyable experience. Using k6
, you'll be able to catch performance regression
Ref. https://k6.io/
Installation
Linux
Debian/Ubuntu
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 379CE192D401AB61
echo "deb https://dl.bintray.com/loadimpact/deb stable main" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install k6
⚠️ Caution
If you are behind a firewall or proxy
There have been reports of users being unable to download the key from Ubuntu's keyserver using apt-key command due to firewalls or proxies blocking their requests. If you experience this issue, you may try this alternative approach instead:
wget -q -O - https://bintray.com/user/downloadSubjectPublicKey?username=bintray | sudo > apt-key add
Redhat/CentOS
wget https://bintray.com/loadimpact/rpm/rpm -O bintray-loadimpact-rpm.repo
sudo mv bintray-loadimpact-rpm.repo /etc/yum.repos.d/
sudo yum install k6
Mac (brew)
Brew
brew install k6
Windows (MSI installer)
Download the k6 installer.
Binaries
Grab a prebuilt binary from our Releases page. Install the binary in your PATH to run k6 from any location.
Docker
docker pull loadimpact/k6
Test types
Has 4-main types (ref. https://k6.io/docs/test-types/introduction) :
Smoke test
it is a regular load test, configured for minimal load.
// Ex. "smoke" test criteria
let smoke = {
vus: 1, // 1 user looping for 1 minute
duration: '1m',
thresholds: {
http_req_duration: ['p(99)<1500'], // 99% of requests must complete below 1.5s
},
}
Load test
Load Testing is primarily concerned with assessing the current performance of your system in terms of concurrent users or requests per second. When you want to understand if your system is meeting the performance goals, this is the type of test you'll run.
// Ex. "load" test criteria
let load = {
stages: [
{ duration: '5m', target: 100 }, // simulate ramp-up of traffic from 1 to 100 users over 5 minutes.
{ duration: '10m', target: 100 }, // stay at 100 users for 10 minutes
{ duration: '5m', target: 0 }, // ramp-down to 0 users
],
thresholds: {
http_req_duration: ['p(99)<1500'], // 99% of requests must complete below 1.5s
'status was 200': ['p(99)<1500'], // 99% of requests must complete below 1.5s
},
}
Stress testing
Stress testing is one of many different types of load testing. While load testing is primarily concerned with assessing the systems performance, the purpose of stress testing is to assess the availability and stability of the system under heavy load.
// Ex. "stress" test criteria
let stress = {
stages: [
{ duration: '2m', target: 100 }, // below normal load
{ duration: '5m', target: 100 },
{ duration: '2m', target: 200 }, // normal load
{ duration: '5m', target: 200 },
{ duration: '2m', target: 300 }, // around the breaking point
{ duration: '5m', target: 300 },
{ duration: '2m', target: 400 }, // beyond the breaking point
{ duration: '5m', target: 400 },
{ duration: '10m', target: 0 }, // scale down. Recovery stage.
],
}
Soak test
The soak test uncovers performance and reliability issues stemming from a system being under pressure for an extended period. Reliability issues typically relate to bugs, memory leaks, insufficient storage quotas, incorrect configuration or infrastructure failures. Performance issues typically relate to incorrect database tuning, memory leaks, resource leaks or a large amount of data.
// Ex. "soak" test criteria
let soak = {
stages: [
{ duration: '2m', target: 400 }, // ramp up to 400 users
{ duration: '3h56m', target: 400 }, // stay at 400 for ~4 hours
{ duration: '2m', target: 0 }, // scale down. (optional)
],
}
Run load test
Ex. Run "full" debug HTTP request :
k6 run test-http-request.js --http-debug="full"
Ex. Export debug log to file :
k6 run test-http-request.js --http-debug="full" --logformat=raw 2> debug.html
HTTP Request
Please focus on test-http-request.js
, it is main script. For load test option(criteria), I separate to another file (testing.js
).
To execute it with debugging via log file, you can using command below :
k6 run test-http-request.js --http-debug="full" --logformat=raw 2> debug.html
Code example
test-http-request.js
:
import http from 'k6/http';
import { check, sleep } from 'k6';
import { smoke, load, stress, soak, custom } from './testing.js';
const AUTH = {
host: 'YOUR_AUTH_HOST',
endpoint: '/YOUR_AUTH_ENDPOINT'
};
const TEST = {
host: 'YOUR_API_HOST',
endpoint: '/YOUR_API_ENDPOINT',
params: 'YOUR_PARAMS'
};
export let options = custom;
export function setup() {
// Passing username and password as part of the URL will
// allow us to authenticate using HTTP Basic Auth.
const authUrl = `${AUTH.host}${AUTH.endpoint}`;
const payload = JSON.stringify({
"username": "YOUR_USERNAME",
"password": "YOUR_PASSWORD",
"client_id": "CLIENT_ID_OF_THE_SERVICE",
"client_secret": "CLIENT_SECRET_OF_THE_SERVICE",
"grant_type": "password_or_your_grant_type",
});
let resAuth = http.post(authUrl, payload, null);
console.log(JSON.stringify(resAuth));
return resAuth.json().data;
};
export default function (data) {
console.log(JSON.stringify(data));
const url = `${TEST.host}${TEST.endpoint}?${TEST.params}`;
const params = {
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${data.access_token}`
},
};
let res = http.get(url, params);
for (var p in res.headers) {
console.log(JSON.stringify(res));
}
const result = check(res, {
'testing, is authenticated': data.hasOwnProperty('access_token'),
'testing, request data status was 200': r => r.status == 200,
'testing, some attribute that you want to check': r => r.json().data[0].some_attr == 'EXPECTED_VALUE'
});
sleep(1);
}
testing.js
:
/*
* Set test criteria into this file
*/
// Smoke test:
// it is a regular load test, configured for minimal load.
let smoke = {
vus: 1, // 1 user looping for 1 minute
duration: '1m',
thresholds: {
http_req_duration: ['p(99)<1500'], // 99% of requests must complete below 1.5s
},
}
// Load test:
// Load Testing is primarily concerned with assessing the current performance of your system in terms of concurrent users or requests per second.
// When you want to understand if your system is meeting the performance goals, this is the type of test you'll run.
let load = {
stages: [
{ duration: '5m', target: 100 }, // simulate ramp-up of traffic from 1 to 100 users over 5 minutes.
{ duration: '10m', target: 100 }, // stay at 100 users for 10 minutes
{ duration: '5m', target: 0 }, // ramp-down to 0 users
],
thresholds: {
http_req_duration: ['p(99)<1500'], // 99% of requests must complete below 1.5s
'status was 200': ['p(99)<1500'], // 99% of requests must complete below 1.5s
},
}
// Stress testing:
// Stress testing is one of many different types of load testing.
// While load testing is primarily concerned with assessing the systems performance,
// the purpose of stress testing is to assess the availability and
// stability of the system under heavy load.
let stress = {
stages: [
{ duration: '2m', target: 100 }, // below normal load
{ duration: '5m', target: 100 },
{ duration: '2m', target: 200 }, // normal load
{ duration: '5m', target: 200 },
{ duration: '2m', target: 300 }, // around the breaking point
{ duration: '5m', target: 300 },
{ duration: '2m', target: 400 }, // beyond the breaking point
{ duration: '5m', target: 400 },
{ duration: '10m', target: 0 }, // scale down. Recovery stage.
],
}
// Soak test:
// The soak test uncovers performance and reliability issues stemming
// from a system being under pressure for an extended period.
// Reliability issues typically relate to bugs, memory leaks,
// insufficient storage quotas, incorrect configuration or infrastructure failures.
// Performance issues typically relate to incorrect database tuning, memory leaks,
// resource leaks or a large amount of data.
let soak = {
stages: [
{ duration: '2m', target: 400 }, // ramp up to 400 users
{ duration: '3h56m', target: 400 }, // stay at 400 for ~4 hours
{ duration: '2m', target: 0 }, // scale down. (optional)
],
}
// Custom test
let custom = {
vus: 1, // 1 user looping for 1 minute
duration: '1s',
}
export { smoke, load, stress, soak, custom }