No results for

Powered byAlgolia

Advanced Examples

You can use multiple scenarios in one script, and these scenarios can be run in sequence or in parallel. Some ways that you can combine scenarios include the following:

  • Have different start times to sequence workloads
  • Add per-scenario tags and environment variables
  • Make scenario-specific thresholds.
  • Use multiple scenarios to run different test logic, so that VUs don't run only the default function.

Combine scenarios

With the startTime property, you can configure your script to start some scenarios later than others. To sequence your scenarios, you can combine startTime with the duration options specific to the executor. (this is easiest to do with executors with set durations, like the arrival-rate executors).

This script has two scenarios, contacts and news, which run in sequence:

  1. At the beginning of the test, k6 starts the contacts scenario. 50 VUs try to run as many iterations as possible for 30 seconds.
  2. After 30 seconds, k6 starts the news scenario. 50 VUs each try to run 100 iterations in one minute.

Along with startTime duration, and maxDuration, note the different test logic for each scenario.

multiple-scenarios.js
1import http from 'k6/http';
2
3export const options = {
4 discardResponseBodies: true,
5 scenarios: {
6 contacts: {
7 executor: 'constant-vus',
8 exec: 'contacts',
9 vus: 50,
10 duration: '30s',
11 },
12 news: {
13 executor: 'per-vu-iterations',
14 exec: 'news',
15 vus: 50,
16 iterations: 100,
17 startTime: '30s',
18 maxDuration: '1m',
19 },
20 },
21};
22
23export function contacts() {
24 http.get('https://test.k6.io/contacts.php', {
25 tags: { my_custom_tag: 'contacts' },
26 });
27}
28
29export function news() {
30 http.get('https://test.k6.io/news.php', { tags: { my_custom_tag: 'news' } });
31}

Use different environment variables and tags per scenario.

The previous example sets tags on individual HTTP request metrics. But, you can also set tags per scenario, which applies them to other taggable objects as well.

multiple-scenarios-env-tags.js
1import http from 'k6/http';
2import { fail } from 'k6';
3
4export const options = {
5 discardResponseBodies: true,
6 scenarios: {
7 contacts: {
8 executor: 'constant-vus',
9 exec: 'contacts',
10 vus: 50,
11 duration: '30s',
12 tags: { my_custom_tag: 'contacts' },
13 env: { MYVAR: 'contacts' },
14 },
15 news: {
16 executor: 'per-vu-iterations',
17 exec: 'news',
18 vus: 50,
19 iterations: 100,
20 startTime: '30s',
21 maxDuration: '1m',
22 tags: { my_custom_tag: 'news' },
23 env: { MYVAR: 'news' },
24 },
25 },
26};
27
28export function contacts() {
29 if (__ENV.MYVAR != 'contacts') fail();
30 http.get('https://test.k6.io/contacts.php');
31}
32
33export function news() {
34 if (__ENV.MYVAR != 'news') fail();
35 http.get('https://test.k6.io/news.php');
36}
note

By default, k6 applies a scenario tag to all metrics in each scenario (the value is the scenario name. You can combine these tags with thresholds, or use them to simplify results filtering.

To disable scenario tags, use the --system-tags option.

Run multiple scenario functions, with different thresholds

You can also set different thresholds for different scenario functions. To do this:

  1. Set scenario-specific tags
  2. Set thresholds for these tags.

This test has 3 scenarios, each with different exec functions, tags and environment variables, and thresholds:

multiple-scenarios-complex.js
1import http from 'k6/http';
2import { sleep } from 'k6';
3
4export const options = {
5 scenarios: {
6 my_web_test: {
7 // some arbitrary scenario name
8 executor: 'constant-vus',
9 vus: 50,
10 duration: '5m',
11 gracefulStop: '0s', // do not wait for iterations to finish in the end
12 tags: { test_type: 'website' }, // extra tags for the metrics generated by this scenario
13 exec: 'webtest', // the function this scenario will execute
14 },
15 my_api_test_1: {
16 executor: 'constant-arrival-rate',
17 rate: 90,
18 timeUnit: '1m', // 90 iterations per minute, i.e. 1.5 RPS
19 duration: '5m',
20 preAllocatedVUs: 10, // the size of the VU (i.e. worker) pool for this scenario
21 tags: { test_type: 'api' }, // different extra metric tags for this scenario
22 env: { MY_CROC_ID: '1' }, // and we can specify extra environment variables as well!
23 exec: 'apitest', // this scenario is executing different code than the one above!
24 },
25 my_api_test_2: {
26 executor: 'ramping-arrival-rate',
27 startTime: '30s', // the ramping API test starts a little later
28 startRate: 50,
29 timeUnit: '1s', // we start at 50 iterations per second
30 stages: [
31 { target: 200, duration: '30s' }, // go from 50 to 200 iters/s in the first 30 seconds
32 { target: 200, duration: '3m30s' }, // hold at 200 iters/s for 3.5 minutes
33 { target: 0, duration: '30s' }, // ramp down back to 0 iters/s over the last 30 second
34 ],
35 preAllocatedVUs: 50, // how large the initial pool of VUs would be
36 maxVUs: 100, // if the preAllocatedVUs are not enough, we can initialize more
37 tags: { test_type: 'api' }, // different extra metric tags for this scenario
38 env: { MY_CROC_ID: '2' }, // same function, different environment variables
39 exec: 'apitest', // same function as the scenario above, but with different env vars
40 },
41 },
42 discardResponseBodies: true,
43 thresholds: {
44 // we can set different thresholds for the different scenarios because
45 // of the extra metric tags we set!
46 'http_req_duration{test_type:api}': ['p(95)<250', 'p(99)<350'],
47 'http_req_duration{test_type:website}': ['p(99)<500'],
48 // we can reference the scenario names as well
49 'http_req_duration{scenario:my_api_test_2}': ['p(99)<300'],
50 },
51};
52
53export function webtest() {
54 http.get('https://test.k6.io/contacts.php');
55 sleep(Math.random() * 2);
56}
57
58export function apitest() {
59 http.get(`https://test-api.k6.io/public/crocodiles/${__ENV.MY_CROC_ID}/`);
60 // no need for sleep() here, the iteration pacing will be controlled by the
61 // arrival-rate executors above!
62}