20 |
21 |
22 | ### Why isn't frontend performance testing enough?
23 |
24 | - Frontend performance does not look under the hood
25 | - Without load, it does not test under traffic conditions
26 | - Browser-level load testing is resource intensive and costly
27 |
28 |
29 |
30 |
31 |
32 | 
33 |
34 |
35 |
36 |
37 | ---
38 |
39 | 
40 |
41 | ---
42 |
43 | ## Backend performance testing
44 |
45 | 
46 |
47 |
48 | ---
49 |
50 | ## What does backend performance verifies?
51 |
52 | - **Scalability**
53 | - **Elasticity**
54 | - **Availability**
55 | - **Reliability**
56 | - **Resiliency**
57 | - **Latency**
58 |
59 | ---
60 |
61 |
62 |
63 |
64 | ### Why isn't backend performance testing enough?
65 |
66 | - Ignores user experience
67 | - Scripts can get lengthy to create
68 | - More difficult to maintain
69 |
70 |
71 |
72 |
73 |
74 | 
75 |
76 |
77 |
78 |
79 | ---
80 |
81 | ## Load testing
82 |
83 | - Move to: [03-load-testing](?p=03-load-testing)
84 |
85 |
--------------------------------------------------------------------------------
/slides/03-load-testing/slides.md:
--------------------------------------------------------------------------------
1 |
10 |
11 | ## Load Testing
12 |
13 | **Performance testing != Load testing**
14 |
15 | ---
16 |
17 | ## Common test parameters
18 |
19 | _Test parameters_ include the distribution, shape, and pattern of the load.
20 |
21 | - **Virtual users (VUs)**
22 | - **Iterations**
23 | - **Throughput**
24 | - **User flows**
25 | - **Load profile**
26 | - **Duration**
27 |
28 | ---
29 |
30 | ## How to simulate load
31 |
32 | 1. **Protocol-based load testing**
33 | 2. **Browser-based load testing**
34 | 3. **Hybrid load testing**
35 |
36 | ---
37 |
38 | ## Load test types
39 |
40 | ### Shakeout test
41 |
42 | 
43 |
44 |
45 | ---
46 |
47 | ### Average load test
48 |
49 | 
50 |
51 |
52 | ---
53 |
54 | ### Stress test
55 |
56 | 
57 |
58 |
59 | ---
60 |
61 | ### Soak or endurance test
62 |
63 | 
64 |
65 |
66 | ---
67 |
68 | ### Spike test
69 |
70 | 
71 |
72 |
73 | ---
74 |
75 | ### Breakpoint test
76 |
77 | 
78 |
79 |
80 | ---
81 |
82 | ## Load testing process
83 |
84 |
85 |
86 |
87 | ### High level overview
88 |
89 | - Planning for load testing
90 | - Scripting a load test
91 | - Executing load tests
92 | - Analysis of load testing results
93 |
94 |
95 |
96 |
97 |
98 | 
99 |
100 |
101 |
102 |
103 | ---
104 |
105 | ## k6 OSS
106 |
107 | - Move to: [04-getting-started-with-k6-oss](?p=04-getting-started-with-k6-oss)
108 |
--------------------------------------------------------------------------------
/slides/04-getting-started-with-k6-oss/slides.md:
--------------------------------------------------------------------------------
1 | # Get started with k6 OSS
2 |
3 | ---
4 |
5 | ## Installation
6 |
7 | https://k6.io/docs/getting-started/installation/
8 |
9 | 
10 |
11 |
12 | ---
13 |
14 | ## Writing your first k6 script
15 |
16 | - Create a new file named `test.js`, and open it in your favorite IDE.
17 | - Import the HTTP Client from the built-in module `k6/http`:
18 | - Create and export a default function.
19 |
20 | ```js [1|3-6]
21 | import http from 'k6/http';
22 |
23 | export default function () {
24 | // Any code in the `default` function
25 | // is executed by each k6 virtual user when the test runs.
26 | }
27 | ```
28 |
29 | ---
30 |
31 | ## Writing your first k6 script
32 |
33 | Add the logic for making the actual HTTP call:
34 |
35 | ```js
36 | import http from 'k6/http';
37 |
38 | export default function() {
39 | let url = 'https://httpbin.test.k6.io/post';
40 | let response = http.post(url, 'Hello world!');
41 |
42 | console.log(response.json().data);
43 | }
44 | ```
45 |
46 | ---
47 |
48 | ## Writing your first k6 script
49 |
50 | Alternatively, you can also run `k6 new [filename]` to automatically create a file with the basic boilerplate to get you up and running quickly. 😉
51 |
52 | ---
53 |
54 | ## Hello World: running your k6 script
55 |
56 | Run the command below on a terminal:
57 |
58 | ```js
59 | k6 run test.js
60 | ```
61 |
62 | ---
63 |
64 | You should get something like this:
65 |
66 | ```shell
67 | $ k6 run test.js
68 |
69 | /\ |‾‾| /‾‾/ /‾‾/
70 | /\ / \ | |/ / / /
71 | / \/ \ | ( / ‾‾\
72 | / \ | |\ \ | (‾) |
73 | / __________ \ |__| \__\ \_____/ .io
74 |
75 | execution: local
76 | script: test.js
77 | output: -
78 |
79 | scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
80 | * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)
81 |
82 | INFO[0001] Hello world! source=console
83 |
84 | running (00m00.7s), 0/1 VUs, 1 complete and 0 interrupted iterations
85 | default ✓ [======================================] 1 VUs 00m00.7s/10m0s 1/1 iters, 1 per VU
86 |
87 | data_received..................: 5.9 kB 9.0 kB/s
88 | data_sent......................: 564 B 860 B/s
89 | http_req_blocked...............: avg=524.18ms min=524.18ms med=524.18ms max=524.18ms p(90)=524.18ms p(95)=524.18ms
90 | http_req_connecting............: avg=123.28ms min=123.28ms med=123.28ms max=123.28ms p(90)=123.28ms p(95)=123.28ms
91 | http_req_duration..............: avg=130.19ms min=130.19ms med=130.19ms max=130.19ms p(90)=130.19ms p(95)=130.19ms
92 | { expected_response:true }...: avg=130.19ms min=130.19ms med=130.19ms max=130.19ms p(90)=130.19ms p(95)=130.19ms
93 | http_req_failed................: 0.00% ✓ 0 ✗ 1
94 | http_req_receiving.............: avg=165µs min=165µs med=165µs max=165µs p(90)=165µs p(95)=165µs
95 | http_req_sending...............: avg=80µs min=80µs med=80µs max=80µs p(90)=80µs p(95)=80µs
96 | http_req_tls_handshaking.......: avg=399.48ms min=399.48ms med=399.48ms max=399.48ms p(90)=399.48ms p(95)=399.48ms
97 | http_req_waiting...............: avg=129.94ms min=129.94ms med=129.94ms max=129.94ms p(90)=129.94ms p(95)=129.94ms
98 | http_reqs......................: 1 1.525116/s
99 | iteration_duration.............: avg=654.72ms min=654.72ms med=654.72ms max=654.72ms p(90)=654.72ms p(95)=654.72ms
100 | iterations.....................: 1 1.525116/s
101 |
102 | ```
103 |
104 | ---
105 |
106 | ## k6 CLI
107 |
108 | - Move to: [05-the-k6-cli](?p=05-the-k6-cli)
109 |
--------------------------------------------------------------------------------
/slides/05-the-k6-cli/slides.md:
--------------------------------------------------------------------------------
1 | # The k6 CLI
2 |
3 | ---
4 |
5 | ## Commands
6 |
7 | The three most common commands are:
8 |
9 | | Command | Description | Usage |
10 | | --------- | ------------------------------ | ---------------- |
11 | | `help` | Displays all possible commands | `k6 help` |
12 | | `run` | Executes a k6 script | `k6 run test.js` |
13 | | `version` | Displays installed k6 version | `k6 version` |
14 |
15 | ---
16 |
17 | ## Flags
18 |
19 | | Flag | Description | Usage |
20 | | ---------------------- | -------------------------------------------------------------- | ---------------------------------------- |
21 | | `--help` | Displays possible flags for the given command | `k6 run --help` |
22 | | `--vus` or `-u` | Sets number of virtual users | `k6 run test.js --vus 10 --duration 30s` |
23 | | `--duration` | Sets the duration of the test | `k6 run test.js --duration 10m` |
24 |
25 | ---
26 |
27 | | Flag | Description | Usage |
28 | | ---------------------- | -------------------------------------------------------------- | ---------------------------------------- |
29 | | `--iterations` or `-i` | Instructs k6 to iterate the default function a number of times | `k6 run test.js -i 3` |
30 | | `-e` | Sets an environment variable to pass to the script | `k6 run test.js -e DOMAIN=test.k6.io`
31 |
32 | ---
33 |
34 | ## Getting help: `help`
35 |
36 | Running `k6 help` returns the following:
37 |
38 | ```shell
39 | /\ |‾‾| /‾‾/ /‾‾/
40 | /\ / \ | |/ / / /
41 | / \/ \ | ( / ‾‾\
42 | / \ | |\ \ | (‾) |
43 | / __________ \ |__| \__\ \_____/ .io
44 |
45 | Usage:
46 | k6 [command]
47 |
48 | Available Commands:
49 | archive Create an archive
50 | cloud Run a test on the cloud
51 | convert Convert a HAR file to a k6 script
52 | help Help about any command
53 | inspect Inspect a script or archive
54 | login Authenticate with a service
55 | pause Pause a running test
56 | resume Resume a paused test
57 | run Start a load test
58 | scale Scale a running test
59 | stats Show test metrics
60 | status Show test status
61 | version Show application version
62 |
63 | Flags:
64 | -a, --address string address for the api server (default "localhost:6565")
65 | -c, --config string JSON config file (default "/Users/nic/Library/Application Support/loadimpact/k6/config.json")
66 | -h, --help help for k6
67 | --log-output string change the output for k6 logs, possible values are stderr,stdout,none,loki[=host:port] (default "stderr")
68 | --log-format string log output format
69 | --no-color disable colored output
70 | -q, --quiet disable progress updates
71 | -v, --verbose enable verbose logging
72 |
73 | Use "k6 [command] --help" for more information about a command.
74 | ```
75 |
76 | ---
77 |
78 | ## Execution and Execution Options: `run`
79 |
80 | Another common k6 command is `k6 run [filename].js`.
81 |
82 | ---
83 |
84 | ### The duration flag
85 |
86 | The duration specifies how long the test executes for. You can set this on the command line with the flag `--duration`:
87 |
88 | ```shell
89 | k6 run test.js --duration 30s
90 | ```
91 |
92 | You can use `s`, `h`, and `m` to define the duration.
93 |
94 | ---
95 |
96 | ### The iterations flag
97 |
98 | You can set the number of iterations with the `--iterations` or `-i` flag, like this:
99 |
100 | ```shell
101 | k6 run test.js --iterations 100
102 | k6 run test.js -i 100
103 | ```
104 |
105 | ---
106 |
107 | ### Virtual user flags
108 |
109 | You can adjust the number of virtual users with the `-u` or `--vus`s flag when running the test:
110 |
111 | ```shell
112 | k6 run test.js --vus 10 --duration 1m
113 | k6 run test.js -u 10 --iterations 100
114 | ```
115 |
116 | ---
117 |
118 | ### Environment variables
119 |
120 | To use an environment variable, define the variable in your script:
121 |
122 | ```js [3|5-7]
123 | import http from 'k6/http';
124 |
125 | const hostname = `http://${__ENV.DOMAIN}`;
126 |
127 | export default function () {
128 | let res = http.get(hostname + '/my_messages.php');
129 | }
130 | ```
131 |
132 | ---
133 |
134 | Here's how to do define it during runtime:
135 |
136 | ```shell
137 | k6 run test.js -e DOMAIN=test.k6.io
138 | ```
139 |
140 | ---
141 |
142 | ## Changing settings in k6
143 |
144 | k6 always [prioritizes settings](https://k6.io/docs/using-k6/k6-options/how-to/#order-of-precedence) in this order:
145 |
146 | 
147 |
148 |
149 | ---
150 |
151 | ## Understanding k6 results
152 |
153 | - Move to: [06-understanding-k6-results](?p=06-understanding-k6-results)
154 |
155 |
--------------------------------------------------------------------------------
/slides/06-understanding-k6-results/slides.md:
--------------------------------------------------------------------------------
1 | # k6 results
2 |
3 | ---
4 |
5 | ## The End-of-test summary report
6 |
7 | Here's that output again:
8 |
9 | ```shell
10 | $ k6 run test.js
11 |
12 | /\ |‾‾| /‾‾/ /‾‾/
13 | /\ / \ | |/ / / /
14 | / \/ \ | ( / ‾‾\
15 | / \ | |\ \ | (‾) |
16 | / __________ \ |__| \__\ \_____/ .io
17 |
18 | execution: local
19 | script: test.js
20 | output: -
21 |
22 | scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
23 | * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)
24 |
25 | INFO[0001] Hello world! source=console
26 |
27 | running (00m00.7s), 0/1 VUs, 1 complete and 0 interrupted iterations
28 | default ✓ [======================================] 1 VUs 00m00.7s/10m0s 1/1 iters, 1 per VU
29 |
30 | data_received..................: 5.9 kB 9.0 kB/s
31 | data_sent......................: 564 B 860 B/s
32 | http_req_blocked...............: avg=524.18ms min=524.18ms med=524.18ms max=524.18ms p(90)=524.18ms p(95)=524.18ms
33 | http_req_connecting............: avg=123.28ms min=123.28ms med=123.28ms max=123.28ms p(90)=123.28ms p(95)=123.28ms
34 | http_req_duration..............: avg=130.19ms min=130.19ms med=130.19ms max=130.19ms p(90)=130.19ms p(95)=130.19ms
35 | { expected_response:true }...: avg=130.19ms min=130.19ms med=130.19ms max=130.19ms p(90)=130.19ms p(95)=130.19ms
36 | http_req_failed................: 0.00% ✓ 0 ✗ 1
37 | http_req_receiving.............: avg=165µs min=165µs med=165µs max=165µs p(90)=165µs p(95)=165µs
38 | http_req_sending...............: avg=80µs min=80µs med=80µs max=80µs p(90)=80µs p(95)=80µs
39 | http_req_tls_handshaking.......: avg=399.48ms min=399.48ms med=399.48ms max=399.48ms p(90)=399.48ms p(95)=399.48ms
40 | http_req_waiting...............: avg=129.94ms min=129.94ms med=129.94ms max=129.94ms p(90)=129.94ms p(95)=129.94ms
41 | http_reqs......................: 1 1.525116/s
42 | iteration_duration.............: avg=654.72ms min=654.72ms med=654.72ms max=654.72ms p(90)=654.72ms p(95)=654.72ms
43 | iterations.....................: 1 1.525116/s
44 |
45 | ```
46 |
47 | ---
48 |
49 | ## k6 built-in metrics
50 |
51 | ### Response time
52 |
53 | ```shell
54 | http_req_duration..............: avg=130.19ms min=130.19ms med=130.19ms max=130.19ms p(90)=130.19ms p(95)=130.19ms
55 | ```
56 |
57 | ---
58 |
59 | ### http_req_duration
60 |
61 | > 💡 `http_req_duration` is the value for *all* requests.
62 |
63 | The line below reports the response time for *only* the successful requests.
64 |
65 | ```shell
66 | { expected_response:true }...: avg=130.19ms min=130.19ms med=130.19ms max=130.19ms p(90)=130.19ms p(95)=130.19ms
67 | ```
68 |
69 | ---
70 |
71 | ### Error rate
72 |
73 | The `http_req_failed` metric describes the error rate for the test. The error rate is the number of requests that failed during the test as a percentage of the total requests.
74 |
75 | ```shell
76 | http_req_failed................: 0.00% ✓ 0 ✗ 1
77 | ```
78 |
79 | ---
80 |
81 | ### Number of requests
82 |
83 | The number of total requests sent by all VUs during the test is described in the line below.
84 |
85 | ```shell
86 | http_reqs......................: 1 1.525116/s
87 | ```
88 |
89 | ---
90 |
91 | ### Iteration duration
92 |
93 | The iteration duration is the amount of time it took for k6 to perform a single loop of your VU code.
94 |
95 | ```shell
96 | iteration_duration.............: avg=654.72ms min=654.72ms med=654.72ms max=654.72ms p(90)=654.72ms p(95)=654.72ms
97 | ```
98 |
99 | ---
100 |
101 | ### Number of iterations
102 |
103 | The number of iterations describes how many times k6 looped through your script in total, including the iterations for all VUs.
104 |
105 | ```plain
106 | iterations.....................: 1 1.525116/s
107 | ```
108 |
109 | ---
110 |
111 | ## Adding checks to your k6 script
112 |
113 | - Move to: [07-adding-checks-to-your-script](?p=07-adding-checks-to-your-script)
--------------------------------------------------------------------------------
/slides/07-adding-checks-to-your-script/slides.md:
--------------------------------------------------------------------------------
1 | # k6 checks
2 |
3 | ---
4 |
5 | ## Our script
6 |
7 | ```js
8 | import http from 'k6/http';
9 |
10 | export default function() {
11 | let url = 'https://httpbin.test.k6.io/post';
12 | let response = http.post(url, 'Hello world!');
13 |
14 | console.log(response.json().data);
15 | }
16 | ```
17 |
18 | ---
19 |
20 | ## Add checks to your script
21 |
22 | ```js [1|3-6]
23 | import { check } from 'k6';
24 |
25 | check(response, {
26 | 'Application says hello': (r) => r.body.includes('Hello world!')
27 | });
28 | }
29 | ```
30 |
31 | ---
32 |
33 | ## Let's run our test again!
34 |
35 | Do you remember the command to run the test? 👀
36 |
37 | ```shell
38 | ✓ Application says hello
39 |
40 | checks.........................: 100.00% ✓ 1 ✗ 0
41 | ```
42 |
43 | ---
44 |
45 | ## Failed checks
46 |
47 | ```js
48 | check(response, {
49 | 'Application says hello': (r) => r.body.includes('Bonjour!')
50 | });
51 | }
52 | ```
53 |
54 | ---
55 |
56 | ## Let's run our test again!
57 |
58 | ```shell
59 | ✗ Application says hello
60 | ↳ 0% — ✓ 0 / ✗ 1
61 |
62 | checks.........................: 0.00% ✓ 0 ✗ 1
63 | ```
64 |
65 | ---
66 |
67 | ## Failed checks are not errors!
68 |
69 | > 💡 To make failing checks stop your test, you can [combine them with thresholds](https://k6.io/docs/using-k6/thresholds/#failing-a-load-test-using-checks).
70 |
71 | ---
72 |
73 | ## Making your scripts realistic with think time
74 |
75 | - Move to: [08-adding-think-time](?p=08-adding-think-time)
--------------------------------------------------------------------------------
/slides/08-adding-think-time/slides.md:
--------------------------------------------------------------------------------
1 | # Think time
2 |
3 | ---
4 |
5 | ## What is think time?
6 |
7 | The amount of time that a script pauses during test execution to simulate delays that real users have in the course of using an application.
8 |
9 | ---
10 |
11 | ## When should you use think time?
12 |
13 | - If your test follows a user flow
14 | - If you want to simulate actions that take some time to carry out
15 | - Your load generator, or the machine you're running k6 from, displays high (> 80%) CPU utilization during test execution.
16 |
17 | ---
18 |
19 | ## When should you **NOT** use think time?
20 |
21 | - You want to do a [stress test](https://k6.io/docs/test-types/stress-testing/)
22 | - The API endpoint you're testing experiences a high amount of requests per second in production that occur without delays
23 | - Your load generator can run your test script without crossing the 80% CPU utilization mark.
24 |
25 | ---
26 |
27 | ## k6 Sleep
28 |
29 | ```js [2|11]
30 | import http from 'k6/http';
31 | import { check, sleep } from 'k6';
32 |
33 | export default function() {
34 | let url = 'https://httpbin.test.k6.io/post';
35 | let response = http.post(url, 'Hello world!');
36 | check(response, {
37 | 'Application says hello': (r) => r.body.includes('Hello world!')
38 | });
39 |
40 | sleep(1);
41 | }
42 | ```
43 |
44 | ---
45 |
46 | **Sleep does not affect the response time (`http_req_duration`); the response time is always reported with sleep removed. Sleep is, however, included in the `iteration_duration`.**
47 |
48 | ---
49 |
50 | ## Dynamic think time
51 |
52 | A dynamic think time is more realistic, and simulates real users more accurately.
53 |
54 | ---
55 |
56 | ### Random sleep
57 |
58 | One way to implement dynamic think time is to use the JavaScript `Math.random()` function:
59 |
60 | ```js
61 | sleep(Math.random() * 5);
62 | ```
63 |
64 | ---
65 |
66 | ### Random sleep between
67 |
68 | ```js [1|3]
69 | import { randomIntBetween } from "https://jslib.k6.io/k6-utils/1.0.0/index.js";
70 |
71 | sleep(randomIntBetween(1,5));
72 | ```
73 |
74 | ---
75 |
76 | ## How much think time should you add?
77 |
78 | The real answer is: it depends.
79 |
80 | ---
81 |
82 | ## Let's move to scaling up your test
83 |
84 | - Move to: [09-load-test-options](?p=09-load-test-options)
--------------------------------------------------------------------------------
/slides/09-load-test-options/slides.md:
--------------------------------------------------------------------------------
1 | # k6 Load Test Options
2 |
3 | ---
4 |
5 | ## Script options
6 |
7 | ```js
8 | export let options = {
9 | vus: 10,
10 | iterations: 40,
11 | };
12 | ```
13 |
14 | ---
15 |
16 | > 💡 If you only define VUs and no other test options, you may get the following error:
17 |
18 | ```shell
19 | /\ |‾‾| /‾‾/ /‾‾/
20 | /\ / \ | |/ / / /
21 | / \/ \ | ( / ‾‾\
22 | / \ | |\ \ | (‾) |
23 | / __________ \ |__| \__\ \_____/ .io
24 |
25 | WARN[0000] the `vus=10` option will be ignored, it only works in conjunction with `iterations`, `duration`, or `stages`
26 | execution: local
27 | script: test.js
28 | output: -
29 | ```
30 |
31 | ---
32 |
33 | ## Iterations
34 |
35 | ```js
36 | vus: 10,
37 | iterations: 40,
38 | ```
39 |
40 | > Setting the number of iterations in test options defines it for **all** users.
41 |
42 | ---
43 |
44 | ## Duration
45 |
46 | ```js
47 | vus: 10,
48 | duration: '2m'
49 | ```
50 |
51 | > Setting the duration instructs k6 to repeat the script for each of the VUs until the duration is reached.
52 |
53 | ---
54 |
55 | ## Iterations and durations
56 |
57 | ```js
58 | vus: 10,
59 | duration: '5m',
60 | iterations: 40,
61 | ```
62 |
63 | > If you set the duration in conjunction with setting the number of iterations, the value that ends earlier is used.
64 |
65 | ---
66 |
67 | ## Stages
68 |
69 | Defining iterations and duration creates a _simple load profile_
70 |
71 | 
72 |
73 |
74 | ---
75 |
76 | ## Constand load profile
77 |
78 | What if you want to add a ramp-up or ramp-down, so that the profile looks more like this?
79 |
80 | 
81 |
82 |
83 | ---
84 |
85 | In that case, you may want to use [stages](https://k6.io/docs/using-k6/options/#stages).
86 |
87 | ```js
88 | export let options = {
89 | stages: [
90 | { duration: '30m', target: 100 },
91 | { duration: '1h', target: 100 },
92 | { duration: '5m', target: 0 },
93 | ],
94 | };
95 | ```
96 |
97 | ---
98 |
99 | ## The full script so far
100 |
101 | If you're using stages, here's what your script should look like so far:
102 |
103 | ```js
104 | import http from 'k6/http';
105 | import { check, sleep } from 'k6';
106 |
107 | export let options = {
108 | stages: [
109 | { duration: '30m', target: 100 },
110 | { duration: '1h', target: 100 },
111 | { duration: '5m', target: 0 },
112 | ],
113 | };
114 |
115 | export default function() {
116 | let url = 'https://httpbin.test.k6.io/post';
117 | let response = http.post(url, 'Hello world!');
118 | check(response, {
119 | 'Application says hello': (r) => r.body.includes('Hello world!')
120 | });
121 |
122 | sleep(Math.random() * 5);
123 | }
124 | ```
125 |
126 | ---
127 |
128 | ## Let's set some thresholds
129 |
130 | - Move to [10-setting-test-criteria-with-thresholds](?p=10-setting-test-criteria-with-thresholds)
--------------------------------------------------------------------------------
/slides/10-setting-test-criteria-with-thresholds/slides.md:
--------------------------------------------------------------------------------
1 | # k6 Thresholds
2 |
3 | ---
4 |
5 | ## Add thresholds to your script
6 |
7 | ```js [7-10]
8 | export let options = {
9 | stages: [
10 | { duration: '30m', target: 100 },
11 | { duration: '1h', target: 100 },
12 | { duration: '5m', target: 0 },
13 | ],
14 | thresholds: {
15 | http_req_failed: ['rate<=0.05'],
16 | http_req_duration: ['p(95)<=5000'],
17 | },
18 | };
19 | ```
20 |
21 | ---
22 |
23 | > 💡 Thresholds are **always** based on metrics.
24 |
25 | ---
26 |
27 | ## Types of thresholds
28 |
29 | - Error rate
30 | - Response time
31 | - Checks
32 |
33 | > 💡 Recommended: Use error rate, response time, and checks thresholds in your tests where possible.
34 |
35 | ---
36 |
37 | ### Error rate
38 |
39 | ```js
40 | thresholds: {
41 | http_req_failed: ['rate<=0.05'],
42 | },
43 | ```
44 |
45 | ---
46 |
47 | ### Response time
48 |
49 | ```js
50 | thresholds: {
51 | http_req_duration: ['p(95)<=5000'],
52 | },
53 | ```
54 |
55 | > 💡 Recommended: Start with the 95th percentile response time.
56 |
57 | ---
58 |
59 | #### Using multiple response time thresholds
60 |
61 | ```js
62 | thresholds: {
63 | http_req_duration: ['p(90) < 400', 'p(95) < 800', 'p(99.9) < 2000'],
64 | },
65 | ```
66 |
67 | ---
68 |
69 | ### Checks
70 |
71 | ```js
72 | thresholds: {
73 | checks: ['rate>=0.9'],
74 | },
75 | ```
76 |
77 | ---
78 |
79 | ## Aborting test on fail
80 |
81 | ```js
82 | thresholds: {
83 | http_req_failed: [{
84 | threshold: 'rate<=0.05',
85 | abortOnFail: true,
86 | }],
87 | },
88 | ```
89 |
90 | ---
91 |
92 | ## The full script
93 |
94 | ```js
95 | import http from 'k6/http';
96 | import { check, sleep } from 'k6';
97 |
98 | export let options = {
99 | stages: [
100 | { duration: '30m', target: 100 },
101 | { duration: '1h', target: 100 },
102 | { duration: '5m', target: 0 },
103 | ],
104 | thresholds: {
105 | http_req_failed: [{
106 | threshold: 'rate<=0.05',
107 | abortOnFail: true,
108 | }],
109 | http_req_duration: ['p(95)<=100'],
110 | checks: ['rate>=0.99'],
111 | },
112 | };
113 |
114 | export default function() {
115 | let url = 'https://httpbin.test.k6.io/post';
116 | let response = http.post(url, 'Hello world!');
117 | check(response, {
118 | 'Application says hello': (r) => r.body.includes('Hello world!')
119 | });
120 |
121 | sleep(Math.random() * 5);
122 | }
123 | ```
124 |
125 | ---
126 |
127 | ## Output k6 results in different ways
128 |
129 | - Move to [11-k6-results-output-options](?p=11-k6-results-output-options)
--------------------------------------------------------------------------------
/slides/11-k6-results-output-options/slides.md:
--------------------------------------------------------------------------------
1 | # k6 results
2 |
3 | ---
4 |
5 | ## What we have done so far
6 |
7 | 
8 |
9 | ---
10 |
11 | ## The output option
12 |
13 | 
14 |
15 | ---
16 |
17 | ### Saving k6 results as a CSV
18 |
19 | ```shell
20 | k6 run test.js -o csv=results.csv
21 | ```
22 |
23 | > 💡 You can also use `--out` instead of `-o`.
24 |
25 | ---
26 |
27 | ### CSV results output format
28 |
29 | ```csv
30 | metric_name,timestamp,metric_value,check,error,error_code,expected_response,group,method,name,proto,scenario,service,status,subproto,tls_version,url,extra_tags
31 | http_reqs,1641298536,1.000000,,,,true,,POST,https://httpbin.test.k6.io/post,HTTP/1.1,default,,200,,tls1.2,https://httpbin.test.k6.io/post,
32 | http_req_duration,1641298536,114.365000,,,,true,,POST,https://httpbin.test.k6.io/post,HTTP/1.1,default,,200,,tls1.2,https://httpbin.test.k6.io/post,
33 | http_req_blocked,1641298536,589.667000,,,,true,,POST,https://httpbin.test.k6.io/post,HTTP/1.1,default,,200,,tls1.2,https://httpbin.test.k6.io/post,
34 | http_req_connecting,1641298536,117.517000,,,,true,,POST,https://httpbin.test.k6.io/post,HTTP/1.1,default,,200,,tls1.2,https://httpbin.test.k6.io/post,
35 | http_req_tls_handshaking,1641298536,415.043000,,,,true,,POST,https://httpbin.test.k6.io/post,HTTP/1.1,default,,200,,tls1.2,https://httpbin.test.k6.io/post,
36 | http_req_sending,1641298536,0.251000,,,,true,,POST,https://httpbin.test.k6.io/post,HTTP/1.1,default,,200,,tls1.2,https://httpbin.test.k6.io/post,
37 | http_req_waiting,1641298536,114.010000,,,,true,,POST,https://httpbin.test.k6.io/post,HTTP/1.1,default,,200,,tls1.2,https://httpbin.test.k6.io/post,
38 | http_req_receiving,1641298536,0.104000,,,,true,,POST,https://httpbin.test.k6.io/post,HTTP/1.1,default,,200,,tls1.2,https://httpbin.test.k6.io/post,
39 | http_req_failed,1641298536,0.000000,,,,true,,POST,https://httpbin.test.k6.io/post,HTTP/1.1,default,,200,,tls1.2,https://httpbin.test.k6.io/post,
40 | checks,1641298536,1.000000,Application says hello,,,,,,,,default,,,,,,
41 | vus,1641298536,2.000000,,,,,,,,,,,,,,,
42 | vus_max,1641298536,100.000000,,,,,,,,,,,,,,,
43 | ```
44 |
45 | ---
46 |
47 | ### Saving k6 results as a JSON
48 |
49 | ```shell
50 | k6 run test.js -o json=results.json
51 | ```
52 |
53 | ### JSON results output format
54 |
55 | ```JSON
56 | {"type":"Metric","data":{"name":"http_reqs","type":"counter","contains":"default","tainted":null,"thresholds":[],"submetrics":null,"sub":{"name":"","parent":"","suffix":"","tags":null}},"metric":"http_reqs"}
57 | {"type":"Point","data":{"time":"2022-01-05T12:46:23.603474+01:00","value":1,"tags":{"expected_response":"true","group":"","method":"POST","name":"https://httpbin.test.k6.io/post","proto":"HTTP/1.1","scenario":"default","status":"200","tls_version":"tls1.2","url":"https://httpbin.test.k6.io/post"}},"metric":"http_reqs"}
58 | {"type":"Metric","data":{"name":"http_req_duration","type":"trend","contains":"time","tainted":null,"thresholds":["p(95)<=100"],"submetrics":null,"sub":{"name":"","parent":"","suffix":"","tags":null}},"metric":"http_req_duration"}
59 | {"type":"Point","data":{"time":"2022-01-05T12:46:23.603474+01:00","value":118.96,"tags":{"expected_response":"true","group":"","method":"POST","name":"https://httpbin.test.k6.io/post","proto":"HTTP/1.1","scenario":"default","status":"200","tls_version":"tls1.2","url":"https://httpbin.test.k6.io/post"}},"metric":"http_req_duration"}
60 | {"type":"Metric","data":{"name":"http_req_blocked","type":"trend","contains":"time","tainted":null,"thresholds":[],"submetrics":null,"sub":{"name":"","parent":"","suffix":"","tags":null}},"metric":"http_req_blocked"}
61 | ```
62 |
63 | ---
64 |
65 | ## Grafana Cloud k6
66 |
67 | 
68 |
69 |
70 | ---
71 |
72 | ## Let's wrap this up!
73 |
74 | - Move to [end](?p=end)
75 |
--------------------------------------------------------------------------------
/slides/end/slides.md:
--------------------------------------------------------------------------------
1 | # The End 🎉
2 |
3 | ---
4 |
5 | ## Further learning
6 |
7 | - [k6.io](https://k6.io/)
8 | - [k6.io/docs](https://k6.io/docs/)
9 | - [youtube.com/k6test](https://www.youtube.com/k6test)
10 | - [github.com/grafana/quickpizza](https://github.com/grafana/quickpizza)
11 |
12 | ---
13 |
14 | ## Thank you!
15 |
16 | 
--------------------------------------------------------------------------------
/slides/intro/slides.md:
--------------------------------------------------------------------------------
1 | # k6-Learn Workshop
2 |
3 | https://github.com/grafana/k6-learn
4 |
5 | ---
6 |
7 | ## What will you learn today?
8 |
9 | Performance testing and k6! 💜
10 |
11 | ---
12 |
13 | ## Structure (Beginner)
14 |
15 | I. Performance Testing Principles
16 | - [Introduction to performance testing](?p=01-introduction-to-performance-testing)
17 | - [Frontend vs backend performance testing](?p=02-frontend-vs-backend-performance-testing)
18 | - [Load testing and overview of the load testing process](?p=03-load-testing)
19 |
20 | ---
21 |
22 | ## Structure (Beginner)
23 |
24 | II. k6 Foundations
25 | - [Getting started with k6 OSS](?p=04-getting-started-with-k6-oss)
26 | - [The k6 CLI](?p=05-the-k6-cli)
27 | - [Understanding k6 results](?p=06-understanding-k6-results)
28 | - [Adding checks to your script](?p=07-adding-checks-to-your-script)
29 | - [Adding think time using sleep](?p=08-adding-think-time)
30 | - [k6 load test options](?p=09-load-test-options)
31 | - [Setting test criteria with thresholds](?p=10-setting-test-criteria-with-thresholds)
32 | - [k6 results output options](?p=11-k6-results-output-options)
33 |
34 | ---
35 |
36 | Please: if you have experience with k6, help others during the workshop 🙏
37 |
38 | ---
39 |
40 | ## How will this workshop works?
41 |
42 | 1. I'll go over some basic concepts
43 | 2. We'll do the exercises together
44 | 3. Ask questions!
45 |
46 | ---
47 |
48 | ## Workshop Requirements
49 |
50 | You will need:
51 |
52 | - `k6` OSS installed locally in your machines
53 | - Basic level of JavaScript
54 |
55 | ---
56 |
57 | ## Let's get started!
58 |
59 | - Move to: [01-introduction-to-performance-testing](?p=01-introduction-to-performance-testing) - for beginner
60 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | publicDir: 'slides',
3 | }
--------------------------------------------------------------------------------