Load Testing
Load testing is a type of performance testing that simulates real user traffic on a website or web application in order to determine how it performs under normal and peak usage conditions. The purpose of load testing is to identify any bottlenecks or performance issues that could arise when multiple users access the website simultaneously.
During load testing, virtual users (VUs) are simulated to perform various activities such as browsing pages, submitting forms, and performing other actions that are representative of real user behavior. The number of VUs is gradually increased to the point where the website begins to experience performance degradation, such as slower page load times or increased response times.
The results are used to identify areas of the website that require optimization, such as server infrastructure or code optimization. Load testing can also help organizations plan for peak usage periods, such as during a product launch or holiday season, by determining the website's capacity to handle increased traffic.
There are a number of options out there for load testing of websites. For the purposes of writing this guide we reviewed several options: K6, Loader.io, Web Performance, TestMatick, Loadview, Qualitest, Prolifics Testing, PFLB, Gatling, and QA Madness.
K6, Loader.io, and Gatling seemed to be the most self-serve. K6 and Gatling seemed to be the most developer focussed, while with loader.io, tests are set up via a browser-based interface. We excluded most of the other choices from consideration because their information was more difficult to access than the top three candidates. A scriptable test seemed to be the most readily repeatable, so K6 and Gatling were the most appealing. I happened to find K6 before Gatling, so the rest of this guide will focus on K6.
Getting Started
Get K6 installed: https://k6.io/docs/get-started/installation/
First Test
create a javascript file, we’ll call ours test1.js
to simply load a page and wait 1 second. This wait will come into play when we increase the test duration.
import http from 'k6/http';
import { sleep } from 'k6';
export default function () {
http.get('https://test.k6.io');
sleep(1);
}
In your terminal run k6 run test1.js
As we can see from the run above, we ran one iteration with one virtual user (VU), and the run
took 1.75s including the 1 second wait.
You can change the command to run your test in the cloud by changing k6 run
to k6 cloud
which will prompt you to log in.
More Users!
Now let’s run that same test with 15 Virtual Users and keep the test going for 15s.
k6 run --vus 15 --duration 15s test1.js
Lots of data there, and I wish I could figure out how to get this gif to not loop, but we can see that with 15 virtual users, we were able to complete 173 requests in 15 seconds. With them taking an average of 1.37s including that 1 second wait. The longest one took 2.38s and 90% of them completed within 1.46s.
But will it browse?
So now let’s dig into an example that shows k6 performing some actual browser interaction, I’ve named mine script.js. It logs into a drupal site and confirms that it gets a welcome message:
import http from 'k6/http';
import { chromium } from 'k6/experimental/browser'
import { check } from 'k6';
export default async function () {
const browser = chromium.launch({ headless: true });
const page = browser.newPage();
try {
await page.goto('https://drupalsite.example.com', { waitUntil: 'networkidle' });
page.locator('input[name="name"]').type('username');
page.locator('input[name="pass"]').type('password');
await Promise.all([
page.waitForNavigation(),
page.locator('input[name="op"]').click(),
]);
check(page, {
'body': page.locator('li.account.first').textContent() == 'Hello username',
});
} finally {
page.close();
browser.close();
}
}
The browser feature is an experimental one and needs to be enabled (export K6_BROWSER_ENABLED=true
)or you can prepend K6_BROWSER_ENABLED=true
to the command itself:
K6_BROWSER_ENABLED=true k6 run --vus 10 --duration 30s script.js
I won’t share a gif of the output of this one because it prints a bunch of console messages that dirty the output, but I could see that my old linode-hosted Drupal site does log in successfully, but good definitely use some performance love:
iteration_duration...............: avg=12.11s min=7.89s med=11.56s max=20.42s p(90)=15.36s p(95)=16.4s
changing the expected test in the body check to be unexpected text, caused the output to include this:
Â
Â
Which demonstrates that this can be used as an automated testing tool besides its use as a load testing tool.
Explore the capabilities
There is a lot more that you can do in k6.
There are many more run options that can be supplied by the command line or an options object in the script itself.
There is also a lot more that can be done in the tests. I refer you to the documentation to explore what you can do, and come back to this page to share your findings. They also have a GitHub repo with several examples, including a couple for Pantheon.