Hi @marianafiori
Welcome to the community forums
I’m not sure exactly what’s the scenario you need to simulate. So I’ll share a couple of approaches.
For example, if you use a ramping-vus executor, with a script like the one below (reading users and passwords from a csv file users.csv
):
import exec from 'k6/execution';
import http from 'k6/http';
import { SharedArray } from 'k6/data';
import { sleep } from 'k6';
import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js';
import { randomIntBetween } from "https://jslib.k6.io/k6-utils/1.0.0/index.js";
const sharedData = new SharedArray("Shared Logins", function () {
let data = papaparse.parse(open('users.csv'), { header: true }).data;
return data;
});
export const options = {
discardResponseBodies: true,
scenarios: {
contacts: {
executor: 'ramping-vus',
startVUs: 35,
stages: [
{ duration: '10s', target: 35 },
{ duration: '1m', target: 35 },
{ duration: '20s', target: 70 },
{ duration: '1m', target: 70 },
{ duration: '20s', target: 100 },
{ duration: '1m', target: 100 },
{ duration: '20s', target: 70 },
{ duration: '1m', target: 70 },
{ duration: '10s', target: 35 },
{ duration: '1m', target: 35 },
],
gracefulRampDown: '10s',
},
},
};
export default function () {
console.log(`[VU: ${exec.vu.idInTest}, iteration: ${exec.scenario.iterationInTest}] Starting iteration...`);
console.log('username: ', sharedData[exec.vu.idInTest - 1].username, ' / password: ', sharedData[exec.vu.idInTest - 1].password);
http.get('https://httpbin.test.k6.io/basic-auth/' + sharedData[exec.vu.idInTest - 1].username + '/' + sharedData[exec.vu.idInTest - 1].password);
sleep(randomIntBetween(1, 5));
}
You would get the virtual users you are after, I think. There are different stages, ramping stage when you go from 35 to 70, then steady at 70, etc.
However, the number of iterations/requests the VUs perform will vary. It will depend on the latency (request duration) of your endpoint, whether you add a sleep time to simulate a user behavior, and the duration of the test. With this executor you are having the number of VUs you specify iterate on your VU code as long as it’s defined in the stage duration.
If your scenario is closer to an API test, you could still use that and reduce or remove the sleep. I added a bigger sleep in the example to simulate a human-run workflow.
Usually though, for API testing, we know a fixed number of requests per second (or time unit) we want our API to fulfill. In this case, you might go for a constant arrival rate executor. There you can set the number of requests per time unit you want, and adjust the number of VUs that will be required to achieve the requests per time unit. Again this will depend on the latency of your endpoint, the sleep time (if you set any).
For example, let’s say I want to test 100 requests per second with my previous script. I can see I am able to achieve this with 100 users (preAllocatedVUs
).
import exec from 'k6/execution';
import http from 'k6/http';
import { SharedArray } from 'k6/data';
import { sleep } from 'k6';
import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js';
const sharedData = new SharedArray("Shared Logins", function () {
let data = papaparse.parse(open('users.csv'), { header: true }).data;
return data;
});
export const options = {
discardResponseBodies: true,
scenarios: {
my_scenario1: {
executor: 'constant-arrival-rate',
duration: '2m', // total duration
preAllocatedVUs: 100, // to allocate runtime resources pre all VUs
rate: 100, // number of constant iterations given `timeUnit`
timeUnit: '1s',
},
},
};
export default function () {
console.log(`[VU: ${exec.vu.idInTest}, iteration: ${exec.scenario.iterationInTest}] Starting iteration...`);
console.log('username: ', sharedData[exec.vu.idInTest - 1].username, ' / password: ', sharedData[exec.vu.idInTest - 1].password);
http.get('https://httpbin.test.k6.io/basic-auth/' + sharedData[exec.vu.idInTest - 1].username + '/' + sharedData[exec.vu.idInTest - 1].password);
sleep(0.1);
}
We can get the 100 request per second rate we are after.
This is because the response time is 100ms, and each VU can execute an iteration every second.
With 25 VUs we would get to 100 request per second, since the latency is low (and we have a sleep of 0.1).
preAllocatedVUs: 25,
rate: 100,
timeUnit: '1s',
If we had a response time of 5 seconds, we would need more VUs to reach the same rate.
A few more examples around executors can be found in k6-learn/Modules/III-k6-Intermediate/08-Setting-load-profiles-with-executors.
I hope this helps.
If you can further elaborate on your concrete case, and share your (sanitized) script, we can give advice more tailored to your scenario if needed.
Cheers!