New to K6, for benchmarking my http request I am using K6 in my pipeline. Now here is my code which have two section
first section is responsible for creating an user and second is trying updating the same user using a profileID
which is generated as a part of first request.
import http from "k6/http";
import { check, sleep, group } from "k6";
import { Trend } from "k6/metrics";
import { LOGIN_URL, BASE_URL } from "../test/support/constants/endpoints.js";
import {
generateSampleUserDataFinal,
generateRandomPhoneNumber,
generateRandomOrganisationContactID,
generateRandomUserTypeId,
} from "../test/support/data/perf.sampledata.js";
let TC01_CreateNewUser = new Trend("TC01_CreateNewUser");
let TC02_UpdateExistingUser = new Trend("TC02_UpdateExistingUser");
function login() {
let authResponse = http.post(`${LOGIN_URL}`);
let authData = authResponse.json().data;
if (!authData) {
console.error("Login failed: ", authResponse.body);
}
return authData;
}
function generateRandomSleepTimer() {
let sleepTime = Math.floor(Math.random() * 3 + 1);
return parseInt(sleepTime);
}
export function createNewUser(
authToken,
sleepTime,
generateSampleUserData
) {
group("TC01: Create a new User", function () {
const response = http.post(
`${BASE_URL}/User`,
generateSampleUserData,
{
headers: {
Authorization: authToken,
"Content-Type": "application/json",
},
tags: { name: "Create a new User" },
}
);
const responseDuration = response.timings.duration;
TC01_CreateNewUser.add(responseDuration);
console.log("Response: ", response.body);
profileId = JSON.parse(response.body).data;
const checkResult = check(response, {
"is status 200": (r) => r.status === 200,
});
let responseMessage;
try {
responseMessage = response.json();
} catch (e) {
console.error("Failed to parse JSON response: ", response.body);
}
check(responseMessage, {
"Success!": (r) => r && r.message === "Success!",
});
sleep(sleepTime);
return profileId ;
});
}
export function updateExistingUser(authToken, sleepTime, profileId) {
group("TC02: Update an existing User", function () {
console.log("Profile ID: ====> : ", profileId);
const response = http.put(
`${BASE_URL}/User`,
{
UserProfileID: `${profileId}`,
organisationContactID: `${generateRandomOrganisationContactID()}`,
name: "Performnace Benchmark Testing",
UserTypeID: `${generateRandomUserTypeId()}`,
email: "[email protected]",
phoneNumber: `${generateRandomPhoneNumber()}`
},
{
headers: {
Authorization: authToken,
"Content-Type": "application/json",
},
tags: { name: "Update an existing User" },
}
);
const responseDuration = response.timings.duration;
TC02_UpdateExistingUser.add(responseDuration);
console.log("Response: ", response.body);
const checkResult = check(response, {
"is status 200": (r) => r.status === 200,
});
let responseMessage;
try {
responseMessage = response.json();
} catch (e) {
console.error("Failed to parse JSON response: ", response.body);
}
check(responseMessage, {
"Success!": (r) => r && r.message === "Success!",
});
sleep(sleepTime);
});
}
export default function () {
const authToken = login();
if (!authToken) {
console.error("No auth token, exiting test");
return;
}
const sleepTime = generateRandomSleepTimer();
const UserProfileID = generateRandomUserProfileID();
let generateSampleUserData = generateSampleUserDataFinal(); //This is function which generate a random payload
let profileId;
createNewUser(authToken, sleepTime, generateSampleUserData);
updateExistingUser(authToken, sleepTime, profileId);
}
Getting response for first section
INFO[0001] Response: {"responseCode":200,"message":"Success!","data":"372"} source=console
INFO[0002] Response: {"responseCode":200,"message":"Success!","data":"373"} source=console
INFO[0003] Response: {"responseCode":200,"message":"Success!","data":"374"} source=console
but for second I am getting
INFO[0003] Profile ID: ====> undefined source=console
How to fix this issue ? How I can user data handler to pass data between the function. In JMeter usually I can use a post processer to capture the value and use it further.
let profileId;
createNewUser(authToken, sleepTime, generateSampleUserData);
updateExistingUser(authToken, sleepTime, profileId);
You are never assigning a value to your variable profileId
, which means it will keep its default value of undefined
.
Similarly, you are not returning a value from your function createNewUser
. You are only return a value from your anonymous function passed as the second argument to group
, but you never do anything with the return value:
export function createNewUser(
authToken,
sleepTime,
generateSampleUserData
) {
group("TC01: Create a new User", function () {
const response = …
profileId = JSON.parse(response.body).data;
// …
return profileId ;
});
}
group
already returns the return value of the anonymous function, but you need to return it from createNewUser
too. Also note that profileId
is not declared (e.g. with var
, let
, or const
), which means it will be a global variable.
So putting it altogether to have a working script:
export function createNewUser(
authToken,
sleepTime,
generateSampleUserData) {
return group("TC01: Create a new User", function () {
const response = …
const profileId = JSON.parse(response.body).data;
// …
return profileId ;
});
}
export default function () {
// …
const profileId = authToken, sleepTime, generateSampleUserData);
updateExistingUser(authToken, sleepTime, profileId);
}
This has nothing to do with k6 specifically, but follows the general rules of JavaScript: variables only have values if you assign a value to them and you need to return values from functions if you want to use them in the subsequent steps. Needless to say, variables and constants are scoped to the body of their function; you cannot modify them from unrelated functions and variable a
declared in function f
is independent from variable a
declared in function g
.