Score 100% on the quiz to continue
Your first k6 script
Write a script with the default function, http.get(), and sleep(), run it, and read the summary metrics.
A k6 script is a JavaScript file. That is the whole trick, and it is why a tester who already writes Cypress or Playwright tests can be productive with k6 in an afternoon.
What changes is not the language. What changes is that k6 takes your script and runs it over and over, in many copies at once, and measures every HTTP request it makes along the way.
The smallest script that does something
Create a file at k6/first-test.js with this content:
import http from 'k6/http'
import { sleep } from 'k6'
export default function () {
http.get('http://localhost:3000/products')
sleep(1)
}That is a complete, valid performance test. Three things are worth naming in it.
The default function
The function exported as default is your test body. k6 calls it once, then calls it again, then again, for as long as the test is configured to run. One pass through it is called an iteration.
This is the biggest mental shift coming from functional testing. In Cypress, your test runs once and then it is over. In k6, your test is a loop body that will be executed thousands of times by hundreds of concurrent virtual users, so anything you put in it happens thousands of times.
👨🏫 That is also why a k6 script has noit()ortest()blocks. There is nothing to name, because the same code runs again and again. The unit of organisation in k6 is the scenario, not the test case.
http.get()
The k6/http module is how you make requests. http.get(url) sends a GET and returns a response object with the fields you would expect:
const response = http.get('http://localhost:3000/products')
console.log(response.status) // 200
console.log(response.timings.duration) // how long it took, in milliseconds
console.log(response.json('total')) // reads a field out of the JSON bodyEvery request made through this module is automatically measured and folded into the metrics k6 prints at the end. You do not instrument anything yourself.
sleep()
sleep(1) pauses the virtual user for one second before it starts the next iteration.
It is tempting to delete it and "test harder". Do not. A virtual user with no sleep() is not a user, it is a tight loop, and it will generate a request pattern no real population of humans would ever produce. We will treat this properly in the lesson on real user flows, where sleep() gets its real name: think time.
Running it
k6 run k6/first-test.jsBy default, k6 runs one virtual user for one iteration and exits. That is deliberate: your first run should tell you whether the script works, not how fast the API is.
Reading the summary
When the run finishes, k6 prints a block of metrics. Trimmed down to what matters today:
checks.........................: 0.00% 0 out of 0
data_received..................: 12 kB 11 kB/s
data_sent......................: 391 B 366 B/s
http_req_duration..............: avg=8.42ms min=8.42ms med=8.42ms max=8.42ms p(90)=8.42ms p(95)=8.42ms
http_req_failed................: 0.00% 0 out of 1
http_reqs......................: 1 0.93/s
iteration_duration.............: avg=1.01s min=1.01s med=1.01s max=1.01s p(90)=1.01s p(95)=1.01s
iterations.....................: 1 0.93/s
vus............................: 1 min=1 max=1Four of those lines carry almost all of the meaning:
http_req_durationis how long the requests took. This is the number people mean when they say "response time".http_req_failedis the error rate.0.00%here, and it is the first thing you should look at, because a fast API that is returning errors is not fast, it is broken.http_reqsis how many requests were made, and the rate per second next to it is your throughput.iterationsis how many times your default function ran.
Notice that avg, min, med, max, and the percentiles are all the same number. With a single request there is only one measurement, so every statistic describes it. That changes the moment you add a second virtual user, and reading those columns properly is what lesson Reading the results is entirely about.
👨🏫 Also noticeiteration_durationis about one second longer thanhttp_req_duration. That is yoursleep(1). Think time counts towards the iteration, not towards the request.
Commands overview 📖
k6 run
Runs a k6 script. With no options, it executes one iteration with one virtual user.
Syntax:
k6 run <script-path>Example:
k6 run k6/first-test.jsk6 run --vus --duration
Overrides the number of virtual users and how long the test runs, straight from the command line.
Syntax:
k6 run --vus <number> --duration <time> <script-path>Example:
k6 run --vus 10 --duration 30s k6/first-test.jsSuggested content 📚
- Running k6 - official documentation
- The k6/http module - official documentation
- Test lifecycle - official documentation
Exercise 🎯
Write k6/first-test.js yourself, run it, and then change one thing at a time to see what each change does to the summary:
- Run it as it is, with the default single iteration.
- Run it again with
--vus 5 --duration 10sand comparehttp_reqsanditerations. - Remove the
sleep(1), run the ten-second version again, and look at what happened tohttp_reqsand tohttp_req_duration. - Put the
sleep(1)back.
🙊 In step 3 you should seehttp_reqsjump by roughly an order of magnitude, because five virtual users with no think time hammer the API as fast as it can answer. Watchhttp_req_durationclimb at the same time: you did not make the API slower, you made the load heavier. This is the first time you will have caused a performance change on purpose, and it is worth sitting with for a minute.
The finished version of this script is in thek6/directory of the course repository.
Show the world what you learned 🌎
To show your professional network what you learned in this lesson, post the following on LinkedIn.
I am taking the "Performance Testing with k6" course by @Walmyr Lima e Silva Filho at the @Talking About Testing School, where I wrote my first k6 script and learned to read the summary metrics it prints: response time, error rate, throughput, and iterations. #TalkingAboutTesting #TATSchool #PerformanceTestingWithK6 #k6 #PerformanceTesting
👨🏫 Remember to tag me in your post. Here is my LinkedIn profile.
Quiz
A k6 script has no `it()` or `test()` blocks, unlike a Cypress or Playwright spec. Why not?
Score 100% on the quiz to continue