Performance Unit Testing with K6

The k6 project hopes to change some of that with a easy, developer-centric load testing tool. By scripting tests using es6 JavaScript in a almost unit testing fashion, it is quite easy to quickly get performance tests created and into your automation workflow....

8 months ago

Latest Post Kubernetes Cheat Sheet by Tyler Moon

As more and more focus is being placed on automated CI / CD pipelines for software development, one area of testing that often gets overlooked until right before release time is performance testing. The k6 project hopes to change some of that with a easy, developer-centric load testing tool. By scripting tests using es6 JavaScript in a almost unit testing fashion, it is quite easy to quickly get performance tests created and into your automation workflow. With a focus on writing performance tests along with unit tests and component tests performance issues can be found earlier in the development cycle and save time and effort later on.

In this article we are going to go over the basics of running k6 using Docker containers, and then take a look at the k6 docker-compose system which uses InfluxDB and Grafana docker images to provide result storage and graphing capabilities.

Note: If you are unfamiliar with Docker containers then check out this article on some of the basics

Prerequisites

Setup

Create a new directory for putting our k6 scripts and examples and then create a script.js file. This will serve as our first performance unit test file. Then copy down the following JavaScript to setup a basic test that hits a website ( the default test website that k6 uses) and then checks that an OK 200 status is returned in under 200 milliseconds.

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

export default function() {
	let res = http.get("http://test.loadimpact.com");
    check(res, {
        "status was 200": (r) => r.status == 200,
        "transaction time OK": (r) => r.timings.duration < 200
    });
    sleep(1);
};

Thats all we need to setup since we are going to run the k6 program out of a Docker container.

First Test Run

Executing the following Docker command will run the k6 image and load in our JavaScript test script.

docker run -i loadimpact/k6 run --vus 10 --duration 30s - <script.js
Note: The first time you use this image it might take a minute for it to download the image layers but after that initial run it should be faster

The --vus 10 flag on that command is where k6 really becomes powerful. Under the hood it is running, in this case 10, "virtual users" at the same time and they are all executing the default function in the script.js file. Think of it like running 10 parallel do while loops. When coding tests for k6 anything inside of the default function, which has to be named as such, is said to be "vus specific" and will run for every test and every virtual user. However, anything outside the default function is initialization code and will only be run once on startup.

Result Storage and Graphing

Now seeing all those cool metrics spew out on the terminal is indeed interesting but to really make use of k6 we might want to store that data for future reference. If we are storing the data then being able to graph it would be useful to look for trends such as your response time getting longer, error codes more prevalent, ect. Luckily k6 has an output setting for JSON files, InfluxDB connections, or Apache Kalfka connections. Another open source project called Grafana can then ingest that data from InfluxDB and graph it in a nice readable fashion.

Since k6 already has a docker-compose setup ready to go lets not reinvent the wheel and just make use of it.

# Clone the source repo
git clone 'https://github.com/loadimpact/k6'
cd k6

# update git submodules
git submodule update --init

# Deploy influxdb and grafana containers in the background
docker-compose up -d influxdb grafana

# Run the k6 container separately so that you don't have to restart influx and grafana every time you want to run your tests
docker-compose run -v $PWD/samples:/scripts k6 run /scripts/es6sample.js

Navigate to https://localhost:3000 to access the Grafana interface. Create a new data source with the following information.

Name: myk6db
Type: InfluxDB
URL: http://influxdb:8086 // Note: this is routed to the influxdb container
Access: Server(Default)
Database: k6
// Leave everything else default

Click "Save & Test" to setup the data source. To use an existing k6 dashboard go to Create -> Import and then enter 2587 into the input field. That will load a dashboard created by Dave Cadwallader with some of the basic k6 metrics on it.

Now run the docker-compose run -v $PWD/samples:/scripts k6 run /scripts/es6sample.js command a few more times to load in some data to view and you should see the metrics on the dashboard update accordingly!

Summary

In this article, we saw how to write a basic performance unit test using es6 JavaScript and the k6 test runner. Then we dove into saving the test data to InfluxDB and viewing it using Grafana. Hopefully this article has been useful and has sparked an interest in more automated performance testing to help with the ever growing CI / CD community.

Tyler Moon

Published 8 months ago

Comments?

Leave us your opinion.