A modern load testing tool for developers and testers in the DevOps era.
Download · Documentation · Community
k6 is a modern load testing tool, building on Load Impact's years of experience in the load and performance testing industry. It provides a clean, approachable scripting API, distributed and cloud execution, with command & control through CLI or a REST API.
This is how load testing should look in the 21st century.
- Scripting in ES6 JS: support for modules to aid code reusability across an organization
- Everything as code: test logic and configuration options are both in JS for version control friendliness
- Automation-friendly: checks (like asserts) and thresholds
- HTTP/1.1, HTTP/2 and WebSocket protocol support
- TLS features: client certificates, configurable SSL/TLS versions and ciphers
- Batteries included: Cookies, Crypto, Custom metrics, Encodings, Environment variables, JSON, HTML forms and more.
- Flexible metrics storage: InfluxDB, JSON or Load Impact Insights
There's even more! See all features available in k6.
brew tap loadimpact/k6
brew install k6
docker pull loadimpact/k6
Grab a prebuilt binary from the Releases page.
To build from source you need Git and Go (1.8 or newer). Follow these instruction for fast building:
- Get source
go get github.com/loadimpact/k6
- Now
cd
to$GOPATH/src/github.com/loadimpact/k6
and rungo build
- Tada, you can now run k6 using
./k6 run script.js
Then make sure to put the k6
binary somewhere in your PATH.
k6 works with the concept of virtual users (VUs), which run scripts - they're essentially glorified, parallel while(true)
loops. Scripts are written using JavaScript, as ES6 modules, which allows you to break larger tests into smaller and more reusable pieces, which makes it easy to scale across an organization.
Scripts must contain, at the very least, a default
function - this defines the entry point for your VUs, similar to the main()
function in many other languages:
export default function() {
// do things here...
}
"Why not just run my script normally, from top to bottom", you might ask - the answer is: we do, but code inside and outside your default
function can do different things.
Code inside default
is called "VU code", and is run over and over for as long as the test is running. Code outside of it is called "init code", and is run only once per VU.
VU code can make HTTP requests, emit metrics, and generally do everything you'd expect a load test to do - with a few important exceptions: you can't load anything from your local filesystem, or import any other modules. This all has to be done from init code.
There are two reasons for this. The first is, of course: performance.
If you read a file from disk on every single script iteration, it'd be needlessly slow; even if you cache the contents of the file and any imported modules, it'd mean the first run of the script would be much slower than all the others. Worse yet, if you have a script that imports or loads things based on things that can only be known at runtime, you'd get slow iterations thrown in every time you load something new.
But there's another, more interesting reason. By forcing all imports and file reads into the init context, we design for distributed execution. We know which files will be needed, so we distribute only those files. We know which modules will be imported, so we can bundle them up from the get-go. And, tying into the performance point above, the other nodes don't even need writable filesystems - everything can be kept in-memory.
As an added bonus, you can use this to reuse data between iterations (but only for the same VU):
var counter = 0;
export default function() {
counter++;
}
First, create a k6 script to describe what the virtual users should do in your load test:
import http from "k6/http";
export default function() {
http.get("http://test.loadimpact.com");
};
Save it as script.js
, then run k6 like this:
k6 run script.js
(Note that if you use the Docker image, the command is slightly different: docker run -i loadimpact/k6 run - <script.js
)
For more information on how to get started running k6, please look at the Running k6 documentation. If you want more info on the scripting API or results output, you'll find that also on https://docs.k6.io.
Types of questions and where to ask:
- How do I? -- Stack Overflow (use tags: k6, javascript, load-testing)
- I got this error, why? -- Stack Overflow
- I got this error and I'm sure it's a bug -- file an issue
- I have an idea/request -- file an issue
- Why do you? -- Slack
- When will you? -- Slack
- I want to contribute/help with development -- Start here, then Slack and issues
To get a basic development environment for k6 setup, first make sure you have Git and Go (1.8 or newer) installed and working properly.
Then you can get the k6 source into your Go workspace ($GOPATH/src
) by running:
go get github.com/loadimpact/k6
Building from source:
Now, standing in the repo root ($GOPATH/src/github.com/loadimpact/k6
) you can build a k6 binary from source by running:
cd $GOPATH/src/github.com/loadimpact/k6
go build
Running the linter:
We make use of the gometalinter
tool to lint the code in CI. To run it locally:
go get -u github.com/alecthomas/gometalinter
gometalinter --install
gometalinter --deadline 10m --config gometalinter.json --vendor ./...
Running the test suite:
To exercise the entire test suite:
go test ./...
To run the tests of a specific package:
go test github.com/loadimpact/k6/core
To run just a specific test case use -run
and pass in a regex that matches the name of the test:
go test ./.. -run ^TestEngineRun$
Combining the two above we can run a specific test case in a specific package:
go test github.com/loadimpact/k6/core -run ^TestEngineRun$
Contributing code:
-
First, find an issue that you'd like to work on
-
Fork repo to your Github account
-
Get a development environment setup (get the source into
$GOPATH/src/github.com/YOUR_ACCOUNT/k6
usinggo get github.com/YOUR_ACCOUNT/k6
) -
Write some code
-
Before creating Pull Request please do the following (the CI will check these things when you create the PR so you can save yourself a roundtrip):
a. Run the Go formatter on the code:
find . -name '*.go' -exec gofmt -s -w {} +
b. Lint the code:
go get -u github.com/alecthomas/gometalinter gometalinter --install gometalinter --deadline 10m --config gometalinter.json --vendor ./...
c. Vendor check the code (make sure all dependencies exists in
vendor/
folder):go get github.com/FiloSottile/vendorcheck vendorcheck ./...
d. Make sure all tests pass:
go test ./...
-
Now you're ready to create the Pull Request!