Let’s start with some questions:
- Have you ever thought about ways to find out if your infrastructure setup could stand under high loads of users?
- Have you ever been able to run a load test without dealing with so many configurations and steep learning curve of current testing tools?
- Have you ever thought about ways to script your way through testing, either for load/performance or otherwise?
- Have you ever thought that load testing can be simplified and be included as part of your CI/CD process?
You are not alone in that. I remember days when I was the lead developer of a team working on developing an API to serve our ever-increasing set of Apps with many micro-services like content- and user-management, billing, analytics and the like. At that time, we used to use the latest best practices in software engineering in source control and CI/CD processes. We have set up our CI/CD process using docker and hosted GitLab and used GitLab CI to deal with CI process. After a while of testing and code-push, we have decided to go with an alpha-stage API that can answer our needs with a new App we used to develop.
After a while of development, testing and improvement, we decided to test our API under load to see if it can hold up to the promises. Since we have seen that after 200,000 users subscribing and 60,000 of them using one of our other Apps, there is an slow-down on the request/response flow to the other API, which roughly had the same setup.
So, in order to not miss the opportunity of (load) testing before customers coming in, we decided to investigate ways to load test our API. After our investigations into Locust, Apache JMeter and the like, we decided to go with Apache JMeter, which was (and still is) the tool of the trade. We thought it would be a good candidate for this purpose. It took us almost three days to be able to learn and execute simple load tests with the GUI version. We were able to produce load test from one server and analyze the results. The results were good, because it gave us a bit more insight into what we should expect from our API, in terms of number of concurrent users and our API’s response time under load.
But later we didn’t use the tool, since there was no clear way to integrate it into our CI/CD process at that time, and we didn’t have enough time to learn and use it. We wanted something more developer-friendly, more integrable to our workflow, and easier to learn. Nowadays, it has been improved very much and it integrates with CI/CD pipelines easily.
Enough said! Let’s dive deep into what load testing is and how we can use k6 for doing load testing on our infrastructure. I will try to write more about the cloud service in the future, too.
Performance testing is a subset of performance engineering in computer science practice which deals with quality assurance of software by putting pressure and workload, either manually or automatically, on the software to see how it behaves and to make sure it is responsive and stable enough under that load. It’s all about expectations. For example, you expect your API or website to serve 10K users simultaneously, but when you put pressure on it, it quickly becomes evident that your calculations differs from the reality and the reverse proves to be the case. Then you should analyze the weak points in your design or setup to see how you can benefit from high load.
There are many types of tests catered for different purposes in performance testing (Source: https://en.wikipedia.org/wiki/Software_performance_testing):
- Load testing: basically, putting load on the system to see how it behaves.
- Stress testing: load testing to find the maximum amount of load the system can handle.
- Soak testing: load testing a system continuously and monitoring for memory leaks and behavior of the system.
- Spike testing: load testing with sudden increase or decrease of the load.
- Breakpoint testing: like stress testing, but incremental load is put on the system over time to see how it behaves.
- Configuration testing: changing configuration to see how the system behaves under different configurations, under load.
- Isolation testing: Isolating a fault domain and repeating the test to confirm the failure.
- Internet testing: global load testing for big companies to see how to system behaves from different regions.
The most common purpose of performance testing is to find out how reliable, stable, performant and responsive the system is. Metrics like throughput and response time is a good measure of such a system.
You can either build the k6 from source or download and install an official binary distribution. There is also an official docker image.
The not-so-beginner approach is to build k6, which obviously you should have Go installed on your machine. To do this, first download and install Go and while having
$GOPATH environment variables set on your shell of choice, run this command:
go get github.com/loadimpact/k6
It will automatically download and install k6 on your machine’s
$GOPATH/bin directory, which you can then run it using the following script:
Once you have saved this script somewhere accessible to k6, naming it
script.js or your own desired file name, you can run it with 10 virtual users (VU) and over a period of 30 seconds, as follows:
k6 run -u 10 -d 30s script.js
It basically runs k6 on your machine using 10 virtual users over the course of 30 seconds, and it checks to see if the test URL returns 200 in all tests.
This was a very short introduction to performance/load testing and the k6 tool. I will try to write more advanced load testing articles to show you how to load test your website and/or API.
This series will continue with more in-depth performance/load testing articles assuming the readers don’t have previous experience on this topic.
As always, I do really appreciate your suggestions, comments and inputs on this.