DEV Community

Hari Bhandari for JankariTech

Posted on

Performance Testing with k6 - 01 - Getting Started

Let's suppose your website/web-app/blog gets popular overnight ( Imagine Elon Musk tweeting about your web app ) and there's a massive spike in the number of visitors/users
accessing your web app. This swelling traffic can overwhelm the web server causing an unintentional distributed denial of service (DDOS) attack. This is a nightmare scenario as people cannot access your web-app.

Now, how do we determine how many users your backend infrastructure can handle?

To answer that, and other performance questions, we have a couple of great performance-testing tools available out there. One of them is k6

What is k6?

k6 is a free and open-source load testing tool written in Go programming language. But you don't need to know Go to write tests using k6.
If you are familiar with the basics of ES2015/ES6, you won't have any headache writing k6 tests.

Installation

To install k6 in your local machine follow the instructions provided here https://k6.io/docs/getting-started/installation/

I am using ubuntu 18.04 but even if you are using another operating system you can follow along.

Your first test:

k6 is based on the concept of virtual users (VUs) that is supposed to simulate the real-time traffic and then execute the script in parallel.

As a rule of thumb, each k6 script must contain at least an exported default function, unless you are using Scenarios.
This default function is the entry point for the VUs, similar to the main() function in Java and other programming languages.

Let's write a simple k6 script that makes a GET request to a test website:

Disclaimer: Make sure load testing is allowed by your web host so that you don't violate their terms of service. In our example, we will be testing a test website https://test.loadimpact.com/

Create a file test.js and add the following content:

import { check } from "k6";
import http from "k6/http";

export default function() {
  let response = http.get("https://test.loadimpact.com/");
  check(response, {
    "is status 200": (r) => r.status === 200
  });
};
Enter fullscreen mode Exit fullscreen mode

Unlike many other JavaScript runtimes, most of the operations in k6 are synchronous i.e. no need to use callbacks and promises.
For example;

http.get(...).then(res =>....)
Enter fullscreen mode Exit fullscreen mode

OR

let response = await http.get(....)
Enter fullscreen mode Exit fullscreen mode

is not needed and we can use synchronous code mentioned in test.js of our example.

Running tests

Then run the k6 script using this command:

k6 run test.js
Enter fullscreen mode Exit fullscreen mode

By default, if nothing is specified (as in the above command), k6 runs a script with only 1 VU and for 1 iteration only. It is useful for debugging, but it's not load testing.

Here a virtual user sends a get request to https://test.loadimpact.com/ and the response status code is checked.

Now we'll run a k6 test with more than 10 virtual users and for a duration of 5 seconds:

 k6 run --vus 10 --duration 5s test.js
Enter fullscreen mode Exit fullscreen mode

Screenshot from 2021-04-27 15-34-44

From the above screenshot:

  • checks = 100%: all of the test run passed
  • vus = 10: 10 virtual users (as provided in the run command)
  • iterations = 126: total number of iterations the test ran. This may vary with each run as we didn't specify the iterations ourself

Now, instead of doing --vus ... --durations .... --iterations.... we can also export an options object to set any options that we want. For example:

export let options = {
    vus: 10,
    duration: 5s
};
export default function() { .... }
Enter fullscreen mode Exit fullscreen mode

What's next?

That all was nice and easy, but not very realistic. It does not matter if you want to test a web frontend or an API, just sending a GET requests does not simulate the user's behavior. In the next parts of this series, we will learn more about k6 in a more realistic way.

Discussion (0)