Skip to content

Commit 1b41136

Browse files
Add "next" version folder (#1402)
* Add "next" version folder * Add apply-patch script to apply changes from a commit to a second directory (#1405) * Add apply-patch script to apply changes from a commit to a second directory Signed-off-by: Jack Baldry <jack.baldry@grafana.com> * Remove confusing usage output Not implemented --------- Signed-off-by: Jack Baldry <jack.baldry@grafana.com> --------- Signed-off-by: Jack Baldry <jack.baldry@grafana.com> Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
1 parent e4e73c8 commit 1b41136

File tree

587 files changed

+47987
-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.

587 files changed

+47987
-0
lines changed

docs/sources/next/_index.md

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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+
## Key features
42+
43+
k6 is packed with features, which you can learn all about in the documentation.
44+
Key features include:
45+
46+
- [CLI tool](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/k6-options/how-to) with developer-friendly APIs.
47+
- Scripting in JavaScript ES2015/ES6 - with support for [local and remote modules](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/modules)
48+
- [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
49+
50+
## Use cases
51+
52+
k6 users are typically Developers, QA Engineers, SDETs, and SREs.
53+
They use k6 for testing the performance and reliability of APIs, microservices, and websites.
54+
Common k6 use cases are:
55+
56+
- **Load testing**
57+
58+
k6 is optimized for minimal resource consumption and designed for running high load tests
59+
([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)).
60+
61+
- **Browser testing**
62+
63+
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.
64+
65+
- **Chaos and resilience testing**
66+
67+
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).
68+
69+
- **Performance and synthetic monitoring**
70+
71+
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.
72+
73+
## Load Testing Manifesto
74+
75+
Our load testing manifesto is the result of having spent years hip deep in the trenches, doing performance- and load testing.
76+
We’ve created it to be used as guidance, helping you in getting your performance testing on the right track!
77+
78+
- [Simple testing is better than no testing](https://k6.io/our-beliefs/#simple-testing-is-better-than-no-testing)
79+
- [Load testing should be goal oriented](https://k6.io/our-beliefs/#load-testing-should-be-goal-oriented)
80+
- [Load testing by developers](https://k6.io/our-beliefs/#load-testing-by-developers)
81+
- [Developer experience is super important](https://k6.io/our-beliefs/#developer-experience-is-super-important)
82+
- [Load test in a pre-production environment](https://k6.io/our-beliefs/#load-test-in-a-pre-production-environment)
83+
84+
## What k6 does not
85+
86+
k6 is a high-performing load testing tool, scriptable in JavaScript. The architectural design to have these capabilities brings some trade-offs:
87+
88+
- **Does not run natively in a browser**
89+
90+
By default, k6 does not render web pages the same way a browser does.
91+
Browsers can consume significant system resources.
92+
Skipping the browser allows running more load within a single machine.
93+
94+
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.
95+
96+
- **Does not run in NodeJS**
97+
98+
JavaScript is not generally well suited for high performance.
99+
To achieve maximum performance, the tool itself is written in Go, embedding a JavaScript runtime allowing for easy test scripting.
100+
101+
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.

docs/sources/next/examples/_index.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
weight: 11
3+
title: Examples
4+
---
5+
6+
# Examples
7+
8+
<!-- TODO: Add content -->
9+
10+
{{< section >}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
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 { randomIntBetween, randomItem, randomString } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';
158+
159+
export const options = {
160+
// for the example, let's run only 1 VU with 1 iteration
161+
vus: 1,
162+
iterations: 1,
163+
};
164+
165+
const USERNAME = `user${randomIntBetween(1, 100000)}@example.com`; // Set your own email;
166+
const PASSWORD = 'superCroc2019';
167+
168+
const session = new Httpx({ baseURL: 'https://test-api.k6.io' });
169+
170+
// Register a new user and retrieve authentication token for subsequent API requests
171+
export function setup() {
172+
let authToken = null;
173+
174+
describe(`setup - create a test user ${USERNAME}`, () => {
175+
const resp = session.post(`/user/register/`, {
176+
first_name: 'Crocodile',
177+
last_name: 'Owner',
178+
username: USERNAME,
179+
password: PASSWORD,
180+
});
181+
182+
expect(resp.status, 'User create status').to.equal(201);
183+
expect(resp, 'User create valid json response').to.have.validJsonBody();
184+
});
185+
186+
describe(`setup - Authenticate the new user ${USERNAME}`, () => {
187+
const resp = session.post(`/auth/token/login/`, {
188+
username: USERNAME,
189+
password: PASSWORD,
190+
});
191+
192+
expect(resp.status, 'Authenticate status').to.equal(200);
193+
expect(resp, 'Authenticate valid json response').to.have.validJsonBody();
194+
authToken = resp.json('access');
195+
expect(authToken, 'Authentication token').to.be.a('string');
196+
});
197+
198+
return authToken;
199+
}
200+
201+
export default function (authToken) {
202+
// set the authorization header on the session for the subsequent requests
203+
session.addHeader('Authorization', `Bearer ${authToken}`);
204+
205+
describe('01. Create a new crocodile', (t) => {
206+
const payload = {
207+
name: `Croc name ${randomString(10)}`,
208+
sex: randomItem(['M', 'F']),
209+
date_of_birth: '2023-05-11',
210+
};
211+
212+
session.addTag('name', 'Create');
213+
const resp = session.post(`/my/crocodiles/`, payload);
214+
215+
expect(resp.status, 'Croc creation status').to.equal(201);
216+
expect(resp, 'Croc creation valid json response').to.have.validJsonBody();
217+
218+
session.newCrocId = resp.json('id');
219+
});
220+
221+
describe('02. Fetch private crocs', (t) => {
222+
session.clearTag('name');
223+
const resp = session.get('/my/crocodiles/');
224+
225+
expect(resp.status, 'Fetch croc status').to.equal(200);
226+
expect(resp, 'Fetch croc valid json response').to.have.validJsonBody();
227+
expect(resp.json().length, 'Number of crocs').to.be.above(0);
228+
});
229+
230+
describe('03. Update the croc', (t) => {
231+
const payload = {
232+
name: `New croc name ${randomString(10)}`,
233+
};
234+
235+
const resp = session.patch(`/my/crocodiles/${session.newCrocId}/`, payload);
236+
237+
expect(resp.status, 'Croc patch status').to.equal(200);
238+
expect(resp, 'Fetch croc valid json response').to.have.validJsonBody();
239+
expect(resp.json('name'), 'Croc name').to.equal(payload.name);
240+
241+
// read "croc" again to verify the update worked
242+
const resp1 = session.get(`/my/crocodiles/${session.newCrocId}/`);
243+
244+
expect(resp1.status, 'Croc fetch status').to.equal(200);
245+
expect(resp1, 'Fetch croc valid json response').to.have.validJsonBody();
246+
expect(resp1.json('name'), 'Croc name').to.equal(payload.name);
247+
});
248+
249+
describe('04. Delete the croc', (t) => {
250+
const resp = session.delete(`/my/crocodiles/${session.newCrocId}/`);
251+
252+
expect(resp.status, 'Croc delete status').to.equal(204);
253+
});
254+
}
255+
```
256+
257+
{{< /code >}}
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)