advanced-example.js
1import http from 'k6/http';2import { check, group, sleep, fail } from 'k6';3
4export const options = {5 stages: [{ target: 70, duration: '30s' }],6 thresholds: {7 'http_req_duration': ['p(95)<500', 'p(99)<1500'],8 'http_req_duration{name:PublicCrocs}': ['avg<400'],9 'http_req_duration{name:Create}': ['avg<600', 'max<1000'],10 },11};12
13function randomString(length, charset = '') {14 if (!charset) charset = 'abcdefghijklmnopqrstuvwxyz';15 let res = '';16 while (length--) res += charset[(Math.random() * charset.length) | 0];17 return res;18}19
20const USERNAME = `${randomString(10)}@example.com`; // Set your own email or `${randomString(10)}@example.com`;21const PASSWORD = 'superCroc2019';22const BASE_URL = 'https://test-api.k6.io';23
24export function setup() {25 // register a new user and authenticate via a Bearer token.26 const res = http.post(`${BASE_URL}/user/register/`, {27 first_name: 'Crocodile',28 last_name: 'Owner',29 username: USERNAME,30 password: PASSWORD,31 });32
33 check(res, { 'created user': (r) => r.status === 201 });34
35 const loginRes = http.post(`${BASE_URL}/auth/token/login/`, {36 username: USERNAME,37 password: PASSWORD,38 });39
40 const authToken = loginRes.json('access');41 check(authToken, { 'logged in successfully': () => authToken !== '' });42
43 return authToken;44}45
46export default (authToken) => {47 const requestConfigWithTag = (tag) => ({48 headers: {49 Authorization: `Bearer ${authToken}`,50 },51 tags: Object.assign(52 {},53 {54 name: 'PrivateCrocs',55 },56 tag57 ),58 });59
60 group('Public endpoints', () => {61 // call some public endpoints in a batch62 const responses = http.batch([63 ['GET', `${BASE_URL}/public/crocodiles/1/`, null, { tags: { name: 'PublicCrocs' } }],64 ['GET', `${BASE_URL}/public/crocodiles/2/`, null, { tags: { name: 'PublicCrocs' } }],65 ['GET', `${BASE_URL}/public/crocodiles/3/`, null, { tags: { name: 'PublicCrocs' } }],66 ['GET', `${BASE_URL}/public/crocodiles/4/`, null, { tags: { name: 'PublicCrocs' } }],67 ]);68
69 const ages = Object.values(responses).map((res) => res.json('age'));70
71 // Functional test: check that all the public crocodiles are older than 572 check(ages, {73 'Crocs are older than 5 years of age': Math.min(...ages) > 5,74 });75 });76
77 group('Create and modify crocs', () => {78 let URL = `${BASE_URL}/my/crocodiles/`;79
80 group('Create crocs', () => {81 const payload = {82 name: `Name ${randomString(10)}`,83 sex: 'M',84 date_of_birth: '2001-01-01',85 };86
87 const res = http.post(URL, payload, requestConfigWithTag({ name: 'Create' }));88
89 if (check(res, { 'Croc created correctly': (r) => r.status === 201 })) {90 URL = `${URL}${res.json('id')}/`;91 } else {92 console.log(`Unable to create a Croc ${res.status} ${res.body}`);93 return;94 }95 });96
97 group('Update croc', () => {98 const payload = { name: 'New name' };99 const res = http.patch(URL, payload, requestConfigWithTag({ name: 'Update' }));100 const isSuccessfulUpdate = check(res, {101 'Update worked': () => res.status === 200,102 'Updated name is correct': () => res.json('name') === 'New name',103 });104
105 if (!isSuccessfulUpdate) {106 console.log(`Unable to update the croc ${res.status} ${res.body}`);107 return;108 }109 });110
111 const delRes = http.del(URL, null, requestConfigWithTag({ name: 'Delete' }));112
113 const isSuccessfulDelete = check(null, {114 'Croc was deleted correctly': () => delRes.status === 204,115 });116
117 if (!isSuccessfulDelete) {118 console.log(`Croc was not deleted properly`);119 return;120 }121 });122
123 sleep(1);124};