高级示例
您可以在一个脚本中使用多个场景,这些场景可以按顺序或并行运行。组合场景的一些方法包括以下几点
- 设置不同的启动时间以按顺序运行工作负载
- 为每个场景添加标签和环境变量
- 设置场景特定的阈值。
- 使用多个场景运行不同的测试逻辑,这样 VU 就不会只运行默认函数。
组合场景
使用 startTime
属性,您可以配置脚本以使某些场景晚于其他场景启动。要按顺序运行场景,可以将 startTime
与执行器特定的 duration 选项结合使用。(对于具有固定 duration 的执行器,例如 arrival-rate 执行器,这样做最容易)。
此脚本包含两个按顺序运行的场景:contacts
和 news
- 测试开始时,k6 启动
contacts
场景。50 个 VU 在 30 秒内尝试运行尽可能多的迭代。 - 30 秒后,k6 启动
news
场景。每个 VU 在一分钟内尝试运行 100 次迭代。
除了 startTime
、duration
和 maxDuration
外,请注意每个场景不同的测试逻辑。
import http from 'k6/http';
export const options = {
discardResponseBodies: true,
scenarios: {
contacts: {
executor: 'constant-vus',
exec: 'contacts',
vus: 5,
duration: '5s',
},
news: {
executor: 'per-vu-iterations',
exec: 'news',
vus: 5,
iterations: 10,
startTime: '10s',
maxDuration: '20s',
},
},
};
export function contacts() {
http.get('https://test.k6.io/contacts.php', {
tags: { my_custom_tag: 'contacts' },
});
}
export function news() {
http.get('https://test.k6.io/news.php', { tags: { my_custom_tag: 'news' } });
}
为每个场景使用不同的环境变量和标签。
前面的示例为单个 HTTP 请求指标设置了标签。但是,您也可以为每个场景设置标签,这也会将其应用于其他可标记对象。
import http from 'k6/http';
import { fail } from 'k6';
export const options = {
discardResponseBodies: true,
scenarios: {
contacts: {
executor: 'constant-vus',
exec: 'contacts',
vus: 50,
duration: '30s',
tags: { my_custom_tag: 'contacts' },
env: { MYVAR: 'contacts' },
},
news: {
executor: 'per-vu-iterations',
exec: 'news',
vus: 50,
iterations: 100,
startTime: '30s',
maxDuration: '1m',
tags: { my_custom_tag: 'news' },
env: { MYVAR: 'news' },
},
},
};
export function contacts() {
if (__ENV.MYVAR != 'contacts') fail();
http.get('https://test.k6.io/contacts.php');
}
export function news() {
if (__ENV.MYVAR != 'news') fail();
http.get('https://test.k6.io/news.php');
}
注意
默认情况下,k6 会为每个场景中的所有指标应用一个
scenario
标签,其值是场景名称。您可以将这些标签与阈值结合使用,或使用它们来简化结果过滤。要禁用场景标签,请使用
--system-tags
选项。
使用不同的阈值运行多个场景函数
您还可以为不同的场景函数设置不同的阈值。为此,请执行以下操作
- 设置场景特定的标签
- 为这些标签设置阈值。
此测试包含 3 个场景,每个场景都有不同的 exec
函数、标签、环境变量和阈值
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
scenarios: {
my_web_test: {
// some arbitrary scenario name
executor: 'constant-vus',
vus: 50,
duration: '5m',
gracefulStop: '0s', // do not wait for iterations to finish in the end
tags: { test_type: 'website' }, // extra tags for the metrics generated by this scenario
exec: 'webtest', // the function this scenario will execute
},
my_api_test_1: {
executor: 'constant-arrival-rate',
rate: 90,
timeUnit: '1m', // 90 iterations per minute, i.e. 1.5 RPS
duration: '5m',
preAllocatedVUs: 10, // the size of the VU (i.e. worker) pool for this scenario
tags: { test_type: 'api' }, // different extra metric tags for this scenario
env: { MY_CROC_ID: '1' }, // and we can specify extra environment variables as well!
exec: 'apitest', // this scenario is executing different code than the one above!
},
my_api_test_2: {
executor: 'ramping-arrival-rate',
startTime: '30s', // the ramping API test starts a little later
startRate: 50,
timeUnit: '1s', // we start at 50 iterations per second
stages: [
{ target: 200, duration: '30s' }, // go from 50 to 200 iters/s in the first 30 seconds
{ target: 200, duration: '3m30s' }, // hold at 200 iters/s for 3.5 minutes
{ target: 0, duration: '30s' }, // ramp down back to 0 iters/s over the last 30 second
],
preAllocatedVUs: 50, // how large the initial pool of VUs would be
maxVUs: 100, // if the preAllocatedVUs are not enough, we can initialize more
tags: { test_type: 'api' }, // different extra metric tags for this scenario
env: { MY_CROC_ID: '2' }, // same function, different environment variables
exec: 'apitest', // same function as the scenario above, but with different env vars
},
},
discardResponseBodies: true,
thresholds: {
// we can set different thresholds for the different scenarios because
// of the extra metric tags we set!
'http_req_duration{test_type:api}': ['p(95)<250', 'p(99)<350'],
'http_req_duration{test_type:website}': ['p(99)<500'],
// we can reference the scenario names as well
'http_req_duration{scenario:my_api_test_2}': ['p(99)<300'],
},
};
export function webtest() {
http.get('https://test.k6.io/contacts.php');
sleep(Math.random() * 2);
}
export function apitest() {
http.get(`https://quickpizza.grafana.com/api/json?crocId=${__ENV.MY_CROC_ID}`);
// no need for sleep() here, the iteration pacing will be controlled by the
// arrival-rate executors above!
}
通过环境变量运行特定场景
k6 默认运行测试脚本中列出的所有场景。但是,通过一些小的代码更改和使用环境变量,您可以通过命令行告诉 k6 仅运行特定场景。
以下示例展示了一个测试脚本,该脚本使用 SCENARIO
环境变量(如果存在)来选择要执行的场景
import http from 'k6/http';
const scenarios = {
my_web_test: {
executor: 'per-vu-iterations',
vus: 1,
iterations: 1,
maxDuration: '30s',
},
my_api_test: {
executor: 'per-vu-iterations',
vus: 1,
iterations: 1,
maxDuration: '30s',
},
};
const { SCENARIO } = __ENV;
export const options = {
// if a scenario is passed via a CLI env variable, then run that scenario. Otherwise, run
// using the pre-configured scenarios above.
scenarios: SCENARIO ? { [SCENARIO]: scenarios[SCENARIO] } : scenarios,
discardResponseBodies: true,
thresholds: {
http_req_duration: ['p(95)<250', 'p(99)<350'],
},
};
export default function () {
const response = http.get('https://quickpizza.grafana.com');
}
然后,您可以通过运行以下命令,从命令行运行测试脚本并仅执行 my_web_test
场景
SCENARIO=my_web_test k6 run script.js
set "SCENARIO=my_web_test" && k6 run script.js
$env:SCENARIO="my_web_test"; k6 run script.js