Skip to content

Commit 553e954

Browse files
committed
update advanced api flow example
1 parent 54b1e51 commit 553e954

File tree

4 files changed

+161
-139
lines changed

4 files changed

+161
-139
lines changed

gatsby-node.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,12 @@ const createRedirects = ({ actions }) => {
16091609
isPermanent: true,
16101610
});
16111611

1612+
createRedirect({
1613+
fromPath: '/examples/advanced-api-flow/',
1614+
toPath: '/examples/api-crud-operations/',
1615+
isPermanent: true,
1616+
});
1617+
16121618
const redirects = {
16131619
'/javascript-api/k6-http/cookiejar-k6-http':
16141620
'/javascript-api/k6-http/cookiejar/',

src/data/doc-examples/links.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@
5555
"to": "/examples/data-uploads"
5656
},
5757
{
58-
"title": "Advanced API example",
59-
"description": "This example covers the usage of different k6 APIs for API load testing.",
58+
"title": "API CRUD Operations",
59+
"description": "This example covers the usage of different k6 APIs for API CRUD operations testing.",
6060
"url": "",
61-
"to": "/examples/advanced-api-flow"
61+
"to": "/examples/api-crud-operations"
6262
},
6363
{
6464
"title": "Generating UUIDs",
@@ -189,4 +189,4 @@
189189
"url": "https://k6.io/blog/extending-k6-with-xk6"
190190
}
191191
]
192-
}
192+
}

src/data/markdown/docs/05 Examples/01 Examples/10 advanced-api-flow.md

Lines changed: 0 additions & 135 deletions
This file was deleted.
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
---
2+
title: 'API CRUD Operations'
3+
excerpt: 'This example covers the usage of k6 to test a REST API CRUD operations.'
4+
---
5+
6+
The example showcases the testing of CRUD operations on a REST API.
7+
8+
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:
9+
10+
- _Create_: HTTP `POST` operation to create a new resource.
11+
- _Read_: HTTP `GET` to retrieve a resource.
12+
- _Update_: HTTP `PUT`or `PATCH` to change an existing resource.
13+
- _Delete_: HTTP `DELETE` to remove a resource.
14+
15+
## Test steps
16+
17+
In the [setup() stage](/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.
18+
19+
The steps implemented in the [VU stage](/using-k6/test-lifecycle/#the-vu-stage) are as follows:
20+
21+
1. _Create_ a new resource, a "croc".
22+
2. _Read_ the list of "crocs".
23+
3. _Update_ the name of the "croc" and _read_ the "croc" to confirm the update operation.
24+
4. _Delete_ the "croc" resource.
25+
26+
<CodeGroup labels={["api-crud-operations.js"]} lineNumbers={[true]}>
27+
28+
```javascript
29+
import { describe, expect } from 'https://jslib.k6.io/k6chaijs/4.3.4.3/index.js';
30+
import { Httpx } from 'https://jslib.k6.io/httpx/0.1.0/index.js';
31+
import { randomIntBetween, randomItem } from "https://jslib.k6.io/k6-utils/1.2.0/index.js";
32+
33+
export let options = {
34+
thresholds: {
35+
checks: [{
36+
threshold: 'rate == 1.00', abortOnFail: true,
37+
}],
38+
'http_req_duration': ['p(90)<25000', 'p(95)<30000'],
39+
'http_req_duration{name:Create}': ['avg<15000', 'max<25000'],
40+
},
41+
// for the example, let's run only 1 VU with 1 iteration
42+
vus: 1,
43+
iterations: 1
44+
};
45+
46+
const USERNAME = `user${randomIntBetween(1, 100000)}@example.com`; // Set your own email;
47+
const PASSWORD = 'superCroc2019';
48+
49+
let session = new Httpx({ baseURL: 'https://test-api.k6.io' });
50+
51+
// Create a random string of given length
52+
function randomString(length, charset = '') {
53+
if (!charset) charset = 'abcdefghijklmnopqrstuvwxyz';
54+
let res = '';
55+
while (length--) res += charset[(Math.random() * charset.length) | 0];
56+
return res;
57+
}
58+
59+
// Authenticate user and retrieve authentication token for the API requests
60+
export function setup() {
61+
62+
let authToken = null;
63+
64+
describe(`setup - create a test user ${USERNAME}`, () => {
65+
let resp = session.post(`/user/register/`, {
66+
first_name: 'Crocodile',
67+
last_name: 'Owner',
68+
username: USERNAME,
69+
password: PASSWORD,
70+
});
71+
72+
expect(resp.status, 'User create status').to.equal(201);
73+
expect(resp).to.have.validJsonBody();
74+
});
75+
76+
describe(`setup - Authenticate the new user ${USERNAME}`, () => {
77+
let resp = session.post(`/auth/token/login/`, {
78+
username: USERNAME,
79+
password: PASSWORD
80+
});
81+
82+
expect(resp.status, 'Auth status').to.equal(200);
83+
expect(resp).to.have.validJsonBody();
84+
authToken = resp.json('access');
85+
expect(authToken, 'auth token').to.not.be.null;
86+
});
87+
88+
return authToken;
89+
}
90+
91+
export default function (authToken) {
92+
93+
// set the authorization header on the session for the subsequent requests.
94+
session.addHeader('Authorization', `Bearer ${authToken}`);
95+
96+
describe('01. Create a new crocodile', (t) => {
97+
let payload = {
98+
name: `Croc name ${randomString(10)}`,
99+
sex: randomItem(["M", "F"]),
100+
date_of_birth: '2023-05-11',
101+
};
102+
103+
session.addTag('name', 'Create');
104+
let resp = session.post(`/my/crocodiles/`, payload);
105+
106+
expect(resp.status, 'Croc creation status').to.equal(201);
107+
expect(resp).to.have.validJsonBody();
108+
109+
session.newCrocId = resp.json('id');
110+
})
111+
112+
describe('02. Fetch private crocs', (t) => {
113+
114+
session.clearTag('name');
115+
let resp = session.get('/my/crocodiles/');
116+
117+
expect(resp.status, 'Fetch croc status').to.equal(200);
118+
expect(resp).to.have.validJsonBody();
119+
expect(resp.json().length, 'number of crocs').to.be.above(0);
120+
})
121+
122+
describe('03. Update the croc', (t) => {
123+
let payload = {
124+
name: `New croc name ${randomString(10)}`,
125+
};
126+
127+
let resp = session.patch(`/my/crocodiles/${session.newCrocId}/`, payload);
128+
129+
expect(resp.status, 'Croc patch status').to.equal(200);
130+
expect(resp).to.have.validJsonBody();
131+
expect(resp.json('name')).to.equal(payload.name);
132+
133+
// read "croc" again to verify the update worked
134+
let resp1 = session.get(`/my/crocodiles/${session.newCrocId}/`);
135+
136+
expect(resp1.status, 'Croc fetch status').to.equal(200);
137+
expect(resp1).to.have.validJsonBody();
138+
expect(resp1.json('name')).to.equal(payload.name);
139+
140+
})
141+
142+
describe('04. Delete the croc', (t) => {
143+
144+
let resp = session.delete(`/my/crocodiles/${session.newCrocId}/`);
145+
146+
expect(resp.status, 'Croc delete status').to.equal(204);
147+
});
148+
}
149+
```
150+
151+
</CodeGroup>

0 commit comments

Comments
 (0)