Published on

k6

Authors
  • avatar
    Name
    PatharaNor
    Twitter

k6

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
avatar
PatharaNor
Tech Writer

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

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 }