Skip to content

Commit 0a89fc7

Browse files
committed
Branch out v0.49.x docs
1 parent 2f47ae0 commit 0a89fc7

File tree

616 files changed

+50522
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

616 files changed

+50522
-0
lines changed

docs/sources/v0.49.x/_index.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
---
2+
aliases:
3+
- /docs/k6/
4+
description: 'The k6 documentation covers everything you need to know about k6 OSS, load testing, and performance testing.'
5+
menuTitle: Grafana k6
6+
title: Grafana k6 documentation
7+
weight: -10
8+
---
9+
10+
# Grafana k6 documentation
11+
12+
This documentation will help you go from a total beginner to a seasoned k6 expert!
13+
14+
## Get started
15+
16+
<div class="nav-cards">
17+
<a href={{< relref "./get-started/installation" >}} class="nav-cards__item nav-cards__item--guide">
18+
<h4>🚀 Installation</h4>
19+
<p>Get up and running in no-time, using either a package manager, standalone installer or the official Docker image.</p>
20+
</a>
21+
<a href={{< relref "./get-started/running-k6" >}} class="nav-cards__item nav-cards__item--guide">
22+
<h4>🏎️💨 Running k6</h4>
23+
<p>Write and execute your first load test locally using JavaScript and the k6 API, adding multiple virtual users, checks and ramping stages.</p>
24+
</a>
25+
<a href={{< relref "./get-started/results-output" >}} class="nav-cards__item nav-cards__item--guide">
26+
<h4>⏱ Results output</h4>
27+
<p>Learn how to leverage the results output to gain actionable insight about your application's performance.</p>
28+
</a>
29+
</div>
30+
31+
## What is k6?
32+
33+
Grafana k6 is an open-source load testing tool that makes performance testing easy and productive for engineering teams.
34+
k6 is free, developer-centric, and extensible.
35+
36+
Using k6, you can test the reliability and performance of your systems and catch performance regressions and problems earlier.
37+
k6 will help you to build resilient and performant applications that scale.
38+
39+
k6 is developed by [Grafana Labs](https://grafana.com/) and the community.
40+
41+
Watch the video below to learn more about k6 and why it could be the missing puzzle in your Grafana stack.
42+
43+
{{< youtube id="1mtYVDA2_iQ" >}}
44+
45+
## Key features
46+
47+
k6 is packed with features, which you can learn all about in the documentation.
48+
Key features include:
49+
50+
- [CLI tool](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/k6-options/how-to) with developer-friendly APIs.
51+
- Scripting in JavaScript ES2015/ES6 - with support for [local and remote modules](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/modules)
52+
- [Checks](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/checks) and [Thresholds](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/thresholds) - for goal-oriented, automation-friendly load testing
53+
54+
## Use cases
55+
56+
k6 users are typically Developers, QA Engineers, SDETs, and SREs.
57+
They use k6 for testing the performance and reliability of APIs, microservices, and websites.
58+
Common k6 use cases are:
59+
60+
- **Load testing**
61+
62+
k6 is optimized for minimal resource consumption and designed for running high load tests
63+
([spike](https://grafana.com/docs/k6/<K6_VERSION>/testing-guides/test-types/spike-testing), [stress](https://grafana.com/docs/k6/<K6_VERSION>/testing-guides/test-types/stress-testing), [soak tests](https://grafana.com/docs/k6/<K6_VERSION>/testing-guides/test-types/soak-testing)).
64+
65+
- **Browser testing**
66+
67+
Through [k6 browser](https://grafana.com/docs/k6/<K6_VERSION>/using-k6-browser), you can run browser-based performance testing and catch issues related to browsers only which can be skipped entirely from the protocol level.
68+
69+
- **Chaos and resilience testing**
70+
71+
You can use k6 to simulate traffic as part of your chaos experiments, trigger them from your k6 tests or inject different types of faults in Kubernetes with [xk6-disruptor](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor).
72+
73+
- **Performance and synthetic monitoring**
74+
75+
With k6, you can automate and schedule to trigger tests very frequently with a small load to continuously validate the performance and availability of your production environment.
76+
77+
## Load Testing Manifesto
78+
79+
Our load testing manifesto is the result of having spent years hip deep in the trenches, doing performance- and load testing.
80+
We’ve created it to be used as guidance, helping you in getting your performance testing on the right track!
81+
82+
- [Simple testing is better than no testing](https://k6.io/our-beliefs/#simple-testing-is-better-than-no-testing)
83+
- [Load testing should be goal oriented](https://k6.io/our-beliefs/#load-testing-should-be-goal-oriented)
84+
- [Load testing by developers](https://k6.io/our-beliefs/#load-testing-by-developers)
85+
- [Developer experience is super important](https://k6.io/our-beliefs/#developer-experience-is-super-important)
86+
- [Load test in a pre-production environment](https://k6.io/our-beliefs/#load-test-in-a-pre-production-environment)
87+
88+
## What k6 does not
89+
90+
k6 is a high-performing load testing tool, scriptable in JavaScript. The architectural design to have these capabilities brings some trade-offs:
91+
92+
- **Does not run natively in a browser**
93+
94+
By default, k6 does not render web pages the same way a browser does.
95+
Browsers can consume significant system resources.
96+
Skipping the browser allows running more load within a single machine.
97+
98+
However, with [k6 browser](https://grafana.com/docs/k6/<K6_VERSION>/using-k6-browser), you can interact with real browsers and collect frontend metrics as part of your k6 tests.
99+
100+
- **Does not run in NodeJS**
101+
102+
JavaScript is not generally well suited for high performance.
103+
To achieve maximum performance, the tool itself is written in Go, embedding a JavaScript runtime allowing for easy test scripting.
104+
105+
If you want to import npm modules or libraries using NodeJS APIs, you can [bundle npm modules with webpack](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/modules#bundling-node-modules) and import them in your tests.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
title: Examples
3+
weight: 11
4+
noindex: true
5+
---
6+
7+
# Examples
8+
9+
<!-- TODO: Add content -->
10+
11+
{{< section >}}
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
---
2+
title: 'API CRUD Operations'
3+
excerpt: 'This example covers the usage of k6 to test a REST API CRUD operations.'
4+
weight: 10
5+
---
6+
7+
# API CRUD Operations
8+
9+
The examples showcase the testing of CRUD operations on a REST API.
10+
11+
CRUD refers to the basic operations in a database: Create, Read, Update, and Delete. We can map these operations to HTTP methods in REST APIs:
12+
13+
- _Create_: HTTP `POST` operation to create a new resource.
14+
- _Read_: HTTP `GET` to retrieve a resource.
15+
- _Update_: HTTP `PUT`or `PATCH` to change an existing resource.
16+
- _Delete_: HTTP `DELETE` to remove a resource.
17+
18+
This document has two examples, one that uses the core k6 APIs (`k6/http` and `checks`) and another to show the more recent APIs [`httpx`](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/httpx) and [`k6chaijs`](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/jslib/k6chaijs)).
19+
20+
## Test steps
21+
22+
In the [setup() stage](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/test-lifecycle#setup-and-teardown-stages) we create a user for the [k6 HTTP REST API](https://test-api.k6.io/). We then retrieve and return a bearer token to authenticate the next CRUD requests.
23+
24+
The steps implemented in the [VU stage](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/test-lifecycle#the-vu-stage) are as follows:
25+
26+
1. _Create_ a new resource, a "croc".
27+
2. _Read_ the list of "crocs".
28+
3. _Update_ the name of the "croc" and _read_ the "croc" to confirm the update operation.
29+
4. _Delete_ the "croc" resource.
30+
31+
## Core k6 APIs example
32+
33+
{{< code >}}
34+
35+
```javascript
36+
import http from 'k6/http';
37+
import { check, group, fail } from 'k6';
38+
39+
export const options = {
40+
vus: 1,
41+
iterations: 1,
42+
};
43+
44+
// Create a random string of given length
45+
function randomString(length, charset = '') {
46+
if (!charset) charset = 'abcdefghijklmnopqrstuvwxyz';
47+
let res = '';
48+
while (length--) res += charset[(Math.random() * charset.length) | 0];
49+
return res;
50+
}
51+
52+
const USERNAME = `${randomString(10)}@example.com`; // Set your own email or `${randomString(10)}@example.com`;
53+
const PASSWORD = 'superCroc2019';
54+
55+
const BASE_URL = 'https://test-api.k6.io';
56+
57+
// Register a new user and retrieve authentication token for subsequent API requests
58+
export function setup() {
59+
const res = http.post(`${BASE_URL}/user/register/`, {
60+
first_name: 'Crocodile',
61+
last_name: 'Owner',
62+
username: USERNAME,
63+
password: PASSWORD,
64+
});
65+
66+
check(res, { 'created user': (r) => r.status === 201 });
67+
68+
const loginRes = http.post(`${BASE_URL}/auth/token/login/`, {
69+
username: USERNAME,
70+
password: PASSWORD,
71+
});
72+
73+
const authToken = loginRes.json('access');
74+
check(authToken, { 'logged in successfully': () => authToken !== '' });
75+
76+
return authToken;
77+
}
78+
79+
export default (authToken) => {
80+
// set the authorization header on the session for the subsequent requests
81+
const requestConfigWithTag = (tag) => ({
82+
headers: {
83+
Authorization: `Bearer ${authToken}`,
84+
},
85+
tags: Object.assign(
86+
{},
87+
{
88+
name: 'PrivateCrocs',
89+
},
90+
tag
91+
),
92+
});
93+
94+
let URL = `${BASE_URL}/my/crocodiles/`;
95+
96+
group('01. Create a new crocodile', () => {
97+
const payload = {
98+
name: `Name ${randomString(10)}`,
99+
sex: 'F',
100+
date_of_birth: '2023-05-11',
101+
};
102+
103+
const res = http.post(URL, payload, requestConfigWithTag({ name: 'Create' }));
104+
105+
if (check(res, { 'Croc created correctly': (r) => r.status === 201 })) {
106+
URL = `${URL}${res.json('id')}/`;
107+
} else {
108+
console.log(`Unable to create a Croc ${res.status} ${res.body}`);
109+
return;
110+
}
111+
});
112+
113+
group('02. Fetch private crocs', () => {
114+
const res = http.get(`${BASE_URL}/my/crocodiles/`, requestConfigWithTag({ name: 'Fetch' }));
115+
check(res, { 'retrieved crocs status': (r) => r.status === 200 });
116+
check(res.json(), { 'retrieved crocs list': (r) => r.length > 0 });
117+
});
118+
119+
group('03. Update the croc', () => {
120+
const payload = { name: 'New name' };
121+
const res = http.patch(URL, payload, requestConfigWithTag({ name: 'Update' }));
122+
const isSuccessfulUpdate = check(res, {
123+
'Update worked': () => res.status === 200,
124+
'Updated name is correct': () => res.json('name') === 'New name',
125+
});
126+
127+
if (!isSuccessfulUpdate) {
128+
console.log(`Unable to update the croc ${res.status} ${res.body}`);
129+
return;
130+
}
131+
});
132+
133+
group('04. Delete the croc', () => {
134+
const delRes = http.del(URL, null, requestConfigWithTag({ name: 'Delete' }));
135+
136+
const isSuccessfulDelete = check(null, {
137+
'Croc was deleted correctly': () => delRes.status === 204,
138+
});
139+
140+
if (!isSuccessfulDelete) {
141+
console.log(`Croc was not deleted properly`);
142+
return;
143+
}
144+
});
145+
};
146+
```
147+
148+
{{< /code >}}
149+
150+
## httpx and k6chaijs example
151+
152+
{{< code >}}
153+
154+
```javascript
155+
import { describe, expect } from 'https://jslib.k6.io/k6chaijs/4.3.4.3/index.js';
156+
import { Httpx } from 'https://jslib.k6.io/httpx/0.1.0/index.js';
157+
import {
158+
randomIntBetween,
159+
randomItem,
160+
randomString,
161+
} from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';
162+
163+
export const options = {
164+
// for the example, let's run only 1 VU with 1 iteration
165+
vus: 1,
166+
iterations: 1,
167+
};
168+
169+
const USERNAME = `user${randomIntBetween(1, 100000)}@example.com`; // Set your own email;
170+
const PASSWORD = 'superCroc2019';
171+
172+
const session = new Httpx({ baseURL: 'https://test-api.k6.io' });
173+
174+
// Register a new user and retrieve authentication token for subsequent API requests
175+
export function setup() {
176+
let authToken = null;
177+
178+
describe(`setup - create a test user ${USERNAME}`, () => {
179+
const resp = session.post(`/user/register/`, {
180+
first_name: 'Crocodile',
181+
last_name: 'Owner',
182+
username: USERNAME,
183+
password: PASSWORD,
184+
});
185+
186+
expect(resp.status, 'User create status').to.equal(201);
187+
expect(resp, 'User create valid json response').to.have.validJsonBody();
188+
});
189+
190+
describe(`setup - Authenticate the new user ${USERNAME}`, () => {
191+
const resp = session.post(`/auth/token/login/`, {
192+
username: USERNAME,
193+
password: PASSWORD,
194+
});
195+
196+
expect(resp.status, 'Authenticate status').to.equal(200);
197+
expect(resp, 'Authenticate valid json response').to.have.validJsonBody();
198+
authToken = resp.json('access');
199+
expect(authToken, 'Authentication token').to.be.a('string');
200+
});
201+
202+
return authToken;
203+
}
204+
205+
export default function (authToken) {
206+
// set the authorization header on the session for the subsequent requests
207+
session.addHeader('Authorization', `Bearer ${authToken}`);
208+
209+
describe('01. Create a new crocodile', (t) => {
210+
const payload = {
211+
name: `Croc name ${randomString(10)}`,
212+
sex: randomItem(['M', 'F']),
213+
date_of_birth: '2023-05-11',
214+
};
215+
216+
session.addTag('name', 'Create');
217+
const resp = session.post(`/my/crocodiles/`, payload);
218+
219+
expect(resp.status, 'Croc creation status').to.equal(201);
220+
expect(resp, 'Croc creation valid json response').to.have.validJsonBody();
221+
222+
session.newCrocId = resp.json('id');
223+
});
224+
225+
describe('02. Fetch private crocs', (t) => {
226+
session.clearTag('name');
227+
const resp = session.get('/my/crocodiles/');
228+
229+
expect(resp.status, 'Fetch croc status').to.equal(200);
230+
expect(resp, 'Fetch croc valid json response').to.have.validJsonBody();
231+
expect(resp.json().length, 'Number of crocs').to.be.above(0);
232+
});
233+
234+
describe('03. Update the croc', (t) => {
235+
const payload = {
236+
name: `New croc name ${randomString(10)}`,
237+
};
238+
239+
const resp = session.patch(`/my/crocodiles/${session.newCrocId}/`, payload);
240+
241+
expect(resp.status, 'Croc patch status').to.equal(200);
242+
expect(resp, 'Fetch croc valid json response').to.have.validJsonBody();
243+
expect(resp.json('name'), 'Croc name').to.equal(payload.name);
244+
245+
// read "croc" again to verify the update worked
246+
const resp1 = session.get(`/my/crocodiles/${session.newCrocId}/`);
247+
248+
expect(resp1.status, 'Croc fetch status').to.equal(200);
249+
expect(resp1, 'Fetch croc valid json response').to.have.validJsonBody();
250+
expect(resp1.json('name'), 'Croc name').to.equal(payload.name);
251+
});
252+
253+
describe('04. Delete the croc', (t) => {
254+
const resp = session.delete(`/my/crocodiles/${session.newCrocId}/`);
255+
256+
expect(resp.status, 'Croc delete status').to.equal(204);
257+
});
258+
}
259+
```
260+
261+
{{< /code >}}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
title: 'Bundling and transpilation'
3+
redirect: 'https://github.com/k6io/k6-es6/'
4+
excerpt: |
5+
Reference project demonstrating how to use webpack and babel to bundle
6+
node modules or transpile code to ES5.1+ for usage in k6 tests.
7+
weight: 18
8+
---
9+
10+
# Bundling and transpilation

0 commit comments

Comments
 (0)