场景可以细致配置虚拟用户(VU)与迭代调度。借助场景,可以在负载测试中建立不同工作负载或流量模式。
使用场景的好处包括:
- 测试组织更简单灵活:同一脚本可声明多个场景,每个场景独立执行不同的 JavaScript 函数。
- 模拟更真实的流量:每个场景可以通过专用执行器,采用不同的虚拟用户和迭代调度模式。 executor
- 并行或顺序工作负载:场景彼此独立,默认并行运行;精细设置各场景的 startTime,可以使它们表现为顺序执行。
- 细粒度结果分析:每个场景可分别配置环境变量和指标标签。
配置场景
在 options 对象中使用 scenarios 键配置场景。名称可以自行决定,只要在脚本中唯一即可。
场景名称会出现在结果摘要、标签等位置。
export const options = {
scenarios: {
example_scenario: {
// name of the executor to use
executor: 'shared-iterations',
// common scenario configuration
startTime: '10s',
gracefulStop: '5s',
env: { EXAMPLEVAR: 'testing' },
tags: { example_tag: 'testing' },
// executor-specific configuration
vus: 10,
iterations: 200,
maxDuration: '10s',
},
another_scenario: {
/*...*/
},
},
};
场景执行器
每个 k6 场景的虚拟用户工作负载都由执行器调度。执行器决定测试持续多久、流量恒定还是变化,以及按虚拟用户还是到达率建立负载模型,即闭合模型或开放模型。 open or closed models
场景对象必须在 executor 属性中指定一个预定义执行器名称。执行器决定 k6 如何建立负载,选项包括:
-
按迭代次数。
- shared-iterations:多个虚拟用户共享迭代总数。 shared-iterations
- per-vu-iterations:每个虚拟用户执行指定次数的迭代。 per-vu-iterations
-
按虚拟用户数量。
- constant-VUs:保持固定虚拟用户数量。 constant-VUs
- ramping-vus:按配置阶段调整虚拟用户数量。 ramping-vus
-
按迭代速率。
- constant-arrival-rate:按恒定速率启动迭代。 constant-arrival-rate
- ramping-arrival-rate:按配置阶段调整迭代启动速率。 ramping-arrival-rate
除了通用场景选项,每种执行器还提供与其工作负载相关的专有选项。完整列表见执行器文档。 Executors
场景选项
| 选项 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| executor(必填) | 字符串 | 唯一的执行器名称。允许值见执行器章节。 executors | – |
| startTime | 字符串 | 相对于测试开始的时间偏移;到达该时刻后开始执行本场景。 | "0s" |
| gracefulStop | 字符串 | 强制停止迭代之前,等待迭代完成的时间。详见优雅停止。 Graceful stop | "30s" |
| exec | 字符串 | 需要执行的导出 JavaScript 函数名称。 | "default" |
| env | object | 该场景专用的环境变量。 | {} |
| tags | object | 该场景专用的标签。 Tags | {} |
| options | object | 附加选项,包括浏览器选项。 browser options | {} |
场景示例
这个脚本组合了两个场景,并设置先后启动时间:
- shared_iter_scenario 立即开始。10个虚拟用户尽快完成总计100次迭代;某些用户可能比其他用户执行更多次。
- per_vu_scenario 在10秒后开始。10个虚拟用户各执行10次迭代。
哪个场景耗时更长?可以运行后观察,也可以为其中一个或两个场景添加 maxDuration。
import http from 'k6/http';
export const options = {
scenarios: {
shared_iter_scenario: {
executor: 'shared-iterations',
vus: 10,
iterations: 100,
startTime: '0s',
},
per_vu_scenario: {
executor: 'per-vu-iterations',
vus: 10,
iterations: 10,
startTime: '10s',
},
},
};
export default function () {
http.get('https://test.k6.io/');
}
运行含有场景的脚本时,k6 输出会包含每个场景的概况。例如执行 k6 run scenario-example.js 后,会按如下方式报告场景:
execution: local
script: scenario-example.js
output: -
scenarios: (100.00%) 2 scenarios, 20 max VUs, 10m40s max duration (incl. grace
ful stop):
* shared_iter_scenario: 100 iterations shared among 10 VUs (maxDurati
on: 10m0s, gracefulStop: 30s)
* per_vu_scenario: 10 iterations for each of 10 VUs (maxDuration: 10m
0s, startTime: 10s, gracefulStop: 30s)
完整输出还包含汇总指标,与默认的测试结束摘要相同:
/\ Grafana /‾‾/
/\ / \ |\ __ / /
/ \/ \ | |/ / / ‾‾\
/ \ | ( | (‾) |
/ __________ \ |_|\_\ \_____/
execution: local
script: scenario-example.js
output: -
scenarios: (100.00%) 2 scenarios, 20 max VUs, 10m40s max duration (incl. grace
ful stop):
* shared_iter_scenario: 100 iterations shared among 10 VUs (maxDurati
on: 10m0s, gracefulStop: 30s)
* per_vu_scenario: 10 iterations for each of 10 VUs (maxDuration: 10m
0s, startTime: 10s, gracefulStop: 30s)
█ TOTAL RESULTS
HTTP
http_req_blocked........................................................: avg=24.59ms min=1µs med=4µs max=263.64ms p(90)=22.48ms p(95)=245.04ms
http_req_connecting.....................................................: avg=11.36ms min=0s med=0s max=120.45ms p(90)=10.76ms p(95)=115.19ms
http_req_duration.......................................................: avg=115.25ms min=108.25ms med=115.66ms max=170.62ms p(90)=119.59ms p(95)=121.13ms
{ expected_response:true }............................................: avg=115.25ms min=108.25ms med=115.66ms max=170.62ms p(90)=119.59ms p(95)=121.13ms
http_req_failed.........................................................: 0.00% 0 out of 200
http_req_receiving......................................................: avg=214.61µs min=15µs med=73.5µs max=4.57ms p(90)=253.4µs p(95)=1.08ms
http_req_sending........................................................: avg=17.79µs min=3µs med=12µs max=669µs p(90)=22µs p(95)=25µs
http_req_tls_handshaking................................................: avg=12.01ms min=0s med=0s max=126.23ms p(90)=11.49ms p(95)=120.04ms
http_req_waiting........................................................: avg=115.02ms min=107.7ms med=115.33ms max=170.59ms p(90)=119.54ms p(95)=121.04ms
http_reqs...............................................................: 200 17.489795/s
EXECUTION
iteration_duration......................................................: avg=140.07ms min=108.3ms med=116.14ms max=383.32ms p(90)=187.14ms p(95)=363.64ms
iterations..............................................................: 200 17.489795/s
vus.....................................................................: 10 min=0 max=10
vus_max.................................................................: 20 min=20 max=20
NETWORK
data_received...........................................................: 2.4 MB 209 kB/s
data_sent...............................................................: 26 kB 2.3 kB/s
█ SCENARIO: per_vu_scenario
HTTP
http_req_blocked...................................: avg=23.52ms min=1µs med=4µs max=244.87ms p(90)=22.39ms p(95)=234.84ms
http_req_connecting................................: avg=11.45ms min=0s med=0s max=120.45ms p(90)=10.84ms p(95)=115.81ms
http_req_duration..................................: avg=114.86ms min=108.25ms med=115.74ms max=123.17ms p(90)=120.08ms p(95)=121.13ms
http_req_failed....................................: 0.00% 0 out of 100
http_req_receiving.................................: avg=195.59µs min=15µs med=73.5µs max=4.57ms p(90)=247.5µs p(95)=875.99µs
http_req_sending...................................: avg=20.8µs min=3µs med=12µs max=669µs p(90)=22.1µs p(95)=27.09µs
http_req_tls_handshaking...........................: avg=12.06ms min=0s med=0s max=126.23ms p(90)=11.49ms p(95)=120.61ms
http_req_waiting...................................: avg=114.64ms min=107.78ms med=115.38ms max=123.07ms p(90)=120.04ms p(95)=121.04ms
http_reqs..........................................: 100 8.744897/s
EXECUTION
iteration_duration.................................: avg=138.53ms min=108.3ms med=116.22ms max=363.71ms p(90)=144.44ms p(95)=353.48ms
iterations.........................................: 100 8.744897/s
NETWORK
data_received......................................: 1.2 MB 104 kB/s
data_sent..........................................: 13 kB 1.1 kB/s
█ SCENARIO: shared_iter_scenario
HTTP
http_req_blocked...................................: avg=25.66ms min=1µs med=4µs max=263.64ms p(90)=24.98ms p(95)=256.16ms
http_req_connecting................................: avg=11.27ms min=0s med=0s max=115.37ms p(90)=10.76ms p(95)=115.15ms
http_req_duration..................................: avg=115.65ms min=108.38ms med=115.61ms max=170.62ms p(90)=119.11ms p(95)=120.91ms
http_req_failed....................................: 0.00% 0 out of 100
http_req_receiving.................................: avg=233.63µs min=22µs med=73.5µs max=4.22ms p(90)=324.6µs p(95)=1.11ms
http_req_sending...................................: avg=14.77µs min=3µs med=12µs max=128µs p(90)=20µs p(95)=22µs
http_req_tls_handshaking...........................: avg=11.96ms min=0s med=0s max=124.34ms p(90)=11.64ms p(95)=118.98ms
http_req_waiting...................................: avg=115.4ms min=107.7ms med=115.33ms max=170.59ms p(90)=118.94ms p(95)=120.85ms
http_reqs..........................................: 100 8.744897/s
EXECUTION
iteration_duration.................................: avg=141.6ms min=108.46ms med=116.09ms max=383.32ms p(90)=189.98ms p(95)=375.24ms
iterations.........................................: 100 8.744897/s
NETWORK
data_received......................................: 1.2 MB 104 kB/s
data_sent..........................................: 13 kB 1.1 kB/s
running (00m12.8s), 00/20 VUs, 200 complete and 0 interrupted iterations
shared_iter_scenario ✓ [ 100% ] 10 VUs 00m02.7s/10m0s 100/100 shared iters
per_vu_scenario ✓ [ 100% ] 10 VUs 00m02.8s/10m0s 100/100 iters, 10 per V
运行选定场景
使用 –scenario 可以运行多场景脚本中的一部分,无需修改脚本或额外增加环境变量逻辑。例如,只运行正在开发的 API 方法对应的负载,或每次提交运行子集、较低频率运行全量测试。选中场景保留原本配置的负载。 –scenario
将下面示例保存为 scenarios.js:
export const options = {
scenarios: {
api: {
executor: 'shared-iterations',
vus: 1,
iterations: 2,
exec: 'api',
},
checkout: {
executor: 'shared-iterations',
vus: 1,
iterations: 3,
exec: 'checkout',
},
},
thresholds: {
iterations: ['count>0'],
'iterations{scenario:api}': ['count>0'],
'iterations{scenario:checkout}': ['count>0'],
},
};
export function api() {
console.log('API iteration');
}
export function checkout() {
console.log('Checkout iteration');
}
选择一个名称,或用逗号分隔多个名称:
k6 run --scenario checkout scenarios.js
k6 run --scenario api,checkout scenarios.js
第一条命令执行3次 checkout 迭代,第二条按各自配置的迭代次数运行两个场景。选择操作保留各场景的执行器、负载、时间设置、函数、环境变量、标签和浏览器设置。其他全局选项和正常测试生命周期仍然适用,包括 setup() 和 teardown()。
脚本初始化完成后,名称必须存在于配置的 scenarios 对象中。仅有 default 导出不会定义可选择的场景;–scenario default 要求明确配置 scenarios.default。空选择或未知名称会返回错误。
负载选项与阈值
–scenario 不能与 –vus、–duration、–iterations 或 –stage 同时使用。k6 会忽略脚本、配置文件或环境变量中对应的顶层设置,并输出警告;选中场景内部设置保持不变。执行分段仍然有效,可能减少选中场景实际分配到的工作量。
如果某个阈值的 scenario 标签指定了已配置但被排除的场景,选择操作会删除该阈值并输出警告。例如只选择 checkout 时,会跳过 API 阈值,保留全局和 checkout 阈值。全局阈值、不含 scenario 标签的过滤条件,以及指定选中场景或未配置场景的过滤条件仍有效。因此,预期完整工作负载的全局计数阈值仍可能使部分运行失败。
即使其他场景生成带有被排除场景标签的样本,被跳过的阈值也不会重新启用。例如选中的 checkout 场景产生 scenario:api 标签的自定义指标时,被选择操作移除的 API 阈值不会评估这些样本。决定哪些断言应该共享时,参见特定标签阈值文档。 thresholds for specific tags
云端运行与归档
相同选择方式适用于 k6 cloud run,包括 –local-execution,以及 k6 archive。归档保存选中的场景和剩余阈值,因此重放归档时无需再次指定 –scenario。重放时省略该参数,不会恢复被排除的场景或阈值。
每个选中场景运行一次
要用单次迭代检查选中工作负载,可以组合 –scenario 与 –once。前者选择场景,后者为每个场景配置一个虚拟用户、一次迭代:
k6 run --scenario api,checkout --once scenarios.js
这条命令分别执行一次 API 和 checkout 迭代。各场景保留函数、环境、标签和浏览器设置;–once 将执行器与时间设置重置为 shared-iterations、startTime: ‘0s’、maxDuration: ’10m’、gracefulStop: ’30s’。执行分段不能与 –once 一起使用。仅传 –once 仍会拒绝多场景脚本;显式选择告诉 k6 应运行哪些场景。











暂无评论内容