DEV Community

Poorshad Shaddel
Poorshad Shaddel

Posted on • Originally published at levelup.gitconnected.com on

Load Test your NodeJS app using K6


Load test using k6

What is load testing?

A load test is a type of software testing which is conducted to understand the behavior of the application under a specific expected load. Load testing is performed to determine a system’s behavior under both normal and at peak conditions(reference).

If you are not familiar with this type of test you should know that we always want to know the capability of our software and the number of online users that we can handle. The goal of load tests is giving us an estimation that how we can handle the users and maybe we expect 10'000 users for a special event like Black Friday but we are not sure if we can handle all of them with the resources we have right now or with the structure we have.

So what is the remedy?

The best remedy is to load testing your app before the disaster happened.

What is k6?

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 and problems earlier, allowing you to build resilient systems and robust applications (reference).

What are the other alternatives?

Artillery is a common load test tool for NodeJS applications. There are some other powerful tools for load testing and you can take a look at this article for more details.

Why K6?

  • Scripting in JavaScript ES2015/ES6 — with support for local and remote modules
  • Checks and Thresholds — for goal-oriented, automation-friendly load testing
  • In the case of performance, I read this issueof Gitlab and why they are using K6 instead of Artillery

Now we are going to create a simple express app and test it using K6.

Create a simple Express App

const app = require('express')();

app.get("/:id", (req, res) => {
    const id = req.params.id;
    res.json({
        id
    })
});

app.listen(3000);
Enter fullscreen mode Exit fullscreen mode

This is the simplest possible app we can create using ExpressJS. We instantiated an express app in line 1 and after that, we implemented requests of this format: localhost:3000/someId

K6 Installation

If you are using mac os you can simply install it using : brew install k6

if you are using Ubuntu you can install it using :

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 379CE192D401AB61
echo "deb [https://dl.bintray.com/loadimpact/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
Enter fullscreen mode Exit fullscreen mode

Also, the K6 docker container is available and we can use it in the CI pipelines.

If you are using another OS check the K6 Installation guide.

Implement a Load Test Script

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

export default function () {
    const rnd = Math.floor(Math.random() * 1000);
    const response = http.get(`http://localhost:3000/${rnd}`);
    check(response, {
        "is status 200": (r) => r.status === 200,
        "is id the same we asked": (r) => {
            const id = Number(r.json("id"))
            return id === rnd
        }
    })
}

export let options = {
    vus: 1,
    duration: '5s',
    // thresholds: {
    //     'failed requests': ['rate<0.02'],
    //     http_req_duration: ['p(95)<500'],
    //     http_reqs: ['count>6000']
    // },
};
Enter fullscreen mode Exit fullscreen mode

This is the implementation of a simple load test using K6:

Export a default function : This is the function that going to be called each time K6 wants to send a request.

Sending HTTP Request: for sending requests we use the http module from k6/http . In line 6 we have sent an HTTP request to the endpoint we have in our express application.

Implement Checks: If you want to be sure that you receive the response you expect you can use check module. The first argument is the response and the second argument is an object that keys of the object are the checks and the values are the implementation of the checks which are functions that should return a boolean.

The first check we implemented is checking the status of response using the response.status .

In the second check, we checked the id from the response body. By using json method we can access the response body. The format of using json method is like this: response.json('fieldSelector') . here we used the id field and since it is a string we cast this string to a number to compare it with the value we expect.

Options:

We can pass the options in the command line or we can export the options in the script. our options contain vus that means the number of virtual users we can send requests as different users or we can send requests like that this is only one person who sends these requests. duration is the duration of this load test. Also, we have another useful option named thresholds that is really practical for using K6 in the CI. It fails if the result does not meet the thresholds. For more information about thresholds take a look at this part of k6 docs.

Running the load test

For running the load test we can use this command:

k6 run load-test.js
Enter fullscreen mode Exit fullscreen mode

This is the result on my local machine:

K6 Test Result
K6 test result

As you can see in the results the Express App handled 22962 requests and approximately 4574 requests per second.

Conclusion

Using K6 was really easy since we can implement tests using Javascript and the K6 is developer-friendly.


Top comments (0)