Building a Load Testing Framework using K6.io — The Intro (Part 1)

Building a Load Testing Framework using K6.io — The Intro (Part 1)

Hola!

Welcome to yet another X-parts article series, where I build a Testing Framework from scratch, based on my learnings and hands-on trials and tribulations. I did a similar kind of article series way back in 2020 Building a Test Automation Framework using Cypress.io. Only this time this testing framework is based on the tool that tackles Load Testing, which is k6 (built on Go and the test scripts in JS 👏), which now has been acquired by Grafana Labs.


A Very Brief Introduction

Let us begin with what I like the most about k6: easy to get started with (do your simple test run in minutes), A simple minimal API, pre-defined metrics, and tons of extensions. You head to the Installation Guide and write a minimal script like the below file and that's it (this series is focussed on to complicate that just a bit 😉).

There is a nice article that you can go through for a somewhat more elaborate introduction:

K6: The Load Testing Framework That’s Changing the Game
Performance testing is essential to software development, ensuring that your application can handle the load and stress of real-world…

Los Geht’s!

Let's start by defining the simplest script file which contains a default function (usually this function has no name, but I like to name it testSuite as this houses the actual tests that are run as you will see later):

import http from 'k6/http';

export default function () {
   http.get('https://test.k6.io');
}

a simple k6 test script (test.js)

and then you run the following command:

k6 run test.js

and it runs, giving you pre-built metrics out of the box.

k6 run results

And now we can add some other things in the run command mix such as the number of virtual users and the total number of iterations or durations:

k6 run --vus 10 --iterations 20 test.js

or,

k6 run --vus 10 --duration 20s test.js

where,

vus - virtual users

iterations - number of times to run the script, shared among VUs (ex.--iterations 30, each vue executes atleast 3 iterations)

duration - specifies how long the test executes for.it will run n iterations of the script with specified VUs during the specified time (ex 10s, 10m, 2h etc)

Now this is way better than how you would go about writing a first test script in Jmeter and then some.

Project Structure:

Before I begin let me clarify that k6 is not a Node.js application and neither you would use npm to install dependencies with it.

k6 does not run on Node.js

Now the Initial project structure will look like this:

So we have code/ directory and it houses the actual scripts and some common/ code reused among those scripts. Don't get fixated on the files under the common directory just yet.

Let's add another script, a slightly complex one with k6 lifecycle and options:

import http from 'k6/http';

// ** Init block starts ** //
// k6 options is part of init block
export let options = {
  stages: [
    { duration: '1m', target: 10 },
    { duration: '1m', target: 20 },
    { duration: '1m', target: 0 } 
  ],
};
// ** Init block ends ** //

// set-up code
export function setup() {
  const res = http.get('https://httpbin.test.k6.io/get');
  return { data: res.json() };
}

// actual tests code (run by VUs)
export default function testSuite(data) {
  console.log(JSON.stringify(data));
}

// teardown code
export function teardown(data) {
  console.log(JSON.stringify(data));
}


a slightly complex k6 test script (test.js)

You can read more about k6 lifecycle blocks here:

Test lifecycle
The four distinct lifecycle stages in a k6 test are “init”, “setup”, “VU”, and “teardown”.

Note: you can pass data from setup() to testSuite() and teardown() functions but not from testsuite() to teardown()

in order to run this script we will be using -o or --out param which basically tells in which way to save the run results which could have many options such as csv, json, cloud, dashboard, etc.

k6 run --out csv=reports/result.csv test.js

as you might have noticed in this run command we didn't specify any number of VUs, iterations, or durations; that's because it's being driven by the options that configure test-run behavior. In our case, options specify stages which are defining the run behavior.

Test run result

Essentially, the script runs for a total of 3 minutes with a peak load of 20 users, and will eventually ramp down to 0 users after 3 minutes have elapsed.

Adiós!

GitHub repo:
k6-LoadTestingFramework/Part 01 at main · far11ven/k6-LoadTestingFramework
A Load Testing framework using https://k6.io (https://github.com/grafana/k6) - far11ven/k6-LoadTestingFramework