如何在k6依赖场景间共享参数?(令牌传递异常问题)
问题分析
你的问题核心是k6中不同场景的VU之间无法直接共享变量:
- k6的每个VU都有独立的执行上下文,全局变量
httpReqParams在每个VU中是各自的副本,修改一个VU的变量不会影响其他VU - browser场景的VU和api场景的VU是完全独立的实例,因此browser场景生成的token无法自动传递到api场景的所有VU中
解决方案
通过文件存储实现跨场景、跨VU的token共享,具体步骤如下:
1. 修改browser场景代码,将token写入文件
引入k6的fs模块,在获取到token后将其写入本地JSON文件:
import { sleep } from "k6"; import { writeFile } from "k6/fs"; import performLoginAndPullBearerToken from "../UIAuthenticationClient.js"; const testConfig = JSON.parse(open("./test-options/api_options.json")); export const options = testConfig; export async function browser() { try { const token = await performLoginAndPullBearerToken(); // 将token写入JSON文件 writeFile("./token.json", JSON.stringify({ authorization: `Bearer ${token}` }), { mode: 0o644 }); console.log("Token successfully saved to file"); } catch (error) { console.error("Error fetching token:", error); throw error; // 终止测试,避免api场景使用无效token } }
2. 修改api场景代码,从文件读取token
在每个VU初始化阶段读取token文件,确保所有VU都能获取到同一个token:
import { sleep } from "k6"; import { readFile } from "k6/fs"; import apiStepsLocation from "./utils/api-utils.js"; const testConfig = JSON.parse(open("./test-options/api_options.json")); export const options = testConfig; // 每个VU初始化时读取一次token(仅执行一次) let httpReqParams = { headers: {} }; try { const tokenData = JSON.parse(readFile("./token.json")); httpReqParams.headers["Authorization"] = tokenData.authorization; } catch (error) { console.error("Error reading token file:", error); throw error; // 终止测试,避免无token调用API } export function api() { sleep(1); console.log("Token params:", httpReqParams); // 这里调用API时使用httpReqParams // apiStepsLocation.someApiCall(httpReqParams); }
3. 确保场景执行顺序
你的配置中已经设置api场景startTime: "45s",browser场景maxDuration: "45s"且gracefulStop: "0s",能保证browser场景完成token写入后,api场景才启动,无需额外调整。
注意事项
- 确保k6运行环境有文件读写权限,测试结束后可手动删除
token.json文件,或在测试结束时添加清理逻辑 - 如果token有过期时间,需确保api场景的运行时长不超过token有效期
- 若测试运行在分布式环境(如k6 Cloud),文件存储方式不适用,此时需改用共享数据库或缓存服务传递token
内容的提问来源于stack exchange,提问作者Taras Horuk
相关产品推荐
相关产品推荐

