An Easy Way to Load Test Your Web Apps
12 Feb 2021

An Easy Way to Load Test Your Web Apps

This time, I want to share my positive experience of load testing of one of our web services, by using K6 tool. Moreover, we will see how easily we can integrate this into the GitLab CI pipeline.

When you develop web applications, it’s crucial to have a testing strategy. Nobody argues about the importance of unit, functional, and integration testing. Nevertheless, very often developers forget to test how their application works under high load. Even, when we have a “green light” from all our testing stages, including manual testing, better to not release it to production, until you load test it. Otherwise, nobody can guarantee, that application will work properly when 50 users will use it simultaneously.

In this article I’m going to load test our web application from the previous article.

For that, we are going to use a K6 tool, written in Go, and uses JavaScript for scripting.

k6 is a developer-centric, free and open-source load testing tool built for making performance testing a productive and enjoyable experience.

Let’s install this tool:

brew install k6

If you have different from the macOS operating system, please read about others ways to install here.

Next, we create a loadtests folder in the root of our project and inside we add a test.js file, where we are going to write our load tests scenarios:

import { sleep } from 'k6';
import http from 'k6/http';
import { check } from 'k6';
import { Rate } from 'k6/metrics';

export let errorRate = new Rate('errors');

export let options = {
    // Here we define our scenarios.
    scenarios: {
        sign_in_page_test: {
            executor: 'constant-vus',
            duration: '1m',
            vus: 100, // amount of the virtual users
            tags: { test_type: 'signInPage' },
            exec: 'signInPage',
        },
    },
    // List of thresholds.
    thresholds: {
        http_req_duration: ['avg<500'], // avg response times must be below 0.5s
        errors: ['rate<0.1'], // <10% errors
    },
};

export function signInPage() {
    const res = http.get(getDomain() + '/user/signin');
    // Here we check the response status.
    const result = check(res, {
        'status is 200': (r) => r.status == 200,
    });
    // If it's different from 200, add info to the errorRate.
    errorRate.add(!result);
    sleep(3)
}

// Gets the domain from the environment variables.
function getDomain() {
    return __ENV.DOMAIN;
}

Above, we have declared a scenario to load test /user/signin page with 100 virtual users who continuously accessing our page in parallel.

To run this load test, we need to execute this command in the terminal:

k6 run --env DOMAIN="http://localhost:8777" ./loadtests/test.js

After some time we will see this results output: alt text

As you could notice, all our defined thresholds were satisfied. So far so good!

Now, let’s see how we can integrate load testing to the Gitlab CI pipeline. Fortunately, it’s easy to do :)

Inside .gitlab-ci.yml we need to add this:

stages:
  - loadtest

loadtesting:
  stage: loadtest
  image:
    name: loadimpact/k6:latest
    entrypoint: [ '' ]
  variables:
    DOMAIN: '[your-testing-domain-here]'  
  script:
    - echo "executing K6 load tests in k6 container..."
    - k6 run --env DOMAIN=${DOMAIN} ./loadtests/test.js

That was it! I’ve described just an idea how you can easily integrate the load testing in your development routine. In the real-world situations you might create more complex load testing scenarios, which will help you find weak points of your application and prevent unexpected downtimes.

I wish you happy coding and no pagerduty calls during the night!😉

Related posts

How to test database interactions in golang applications
22 Dec 2020

How to test database interactions in golang applications

Testing of functions with database interactions always was challenging. Recently, I found a wonderful library go-sqlmock which will simplify writing tests and mocking database queries in golang applications a lot.

go testing sql