JMeter通过属性传递线程数失效及计算值传递异常求助
问题场景
配置了setUp线程组和执行业务操作的常规线程组,尝试在setUp线程组的JSR223取样器中设置线程数属性,但常规线程组无法读取该属性。
初始问题表现
在Threads init JSR223取样器中执行以下代码:
props.put("threads", 5); props.put("rampup", 5);
Debug取样器显示属性已成功设置:
JMeterProperties: <...> jmeter.version=5.6.2 not_in_menu=org.apache.jmeter.protocol.mongodb.sampler.MongoScriptSampler,org.apache.jmeter.protocol.mongodb.config.MongoSourceElement,org.apache.jmeter.timers.BSFTimer,org.apache.jmeter.modifiers.BSFPreProcessor,org.apache.jmeter.extractor.BSFPostProcessor,org.apache.jmeter.assertions.BSFAssertion,org.apache.jmeter.visualizers.BSFListener,org.apache.jmeter.protocol.java.sampler.BSFSampler,org.apache.jmeter.protocol.http.control.gui.SoapSamplerGui rampup=7 remote_hosts=127.0.0.1 sampleresult.timestamp.start=true summariser.name=summary system.properties=system.properties threads=7 upgrade_properties=/bin/upgrade.properties user.properties=user.properties <...>
但在常规线程组配置中使用${__P(threads)}或${__Property(threads)}引用属性时,日志显示线程数仍为1:
2023-08-25 17:44:40,166 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=2 delayedStart=false 2023-08-25 17:44:40,167 INFO o.a.j.t.ThreadGroup: Started thread group number 1 2023-08-25 17:44:40,167 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
给属性值添加引号(如"7")后,初始问题暂时解决,但使用预计算值时问题复现。
更新后问题表现
使用以下代码计算线程数:
String[] categories = (vars.get("categories")).split(","); int qty = Math.round(categories.length/2); log.info("!!!!qty variable is "+qty); props.put("threads", qty); props.put("rampup", qty);
日志显示qty值为5,但常规线程组仍无法读取属性:
2023-08-26 10:00:14,006 INFO o.a.j.p.j.s.J.Threads init: !!!!qty variable is 5 2023-08-26 10:00:14,007 INFO o.a.j.t.JMeterThread: Thread is done: setup threads 1-1 2023-08-26 10:00:14,007 INFO o.a.j.t.JMeterThread: Thread finished: setup threads 1-1
问题原因与解决方法
核心原因
JMeter在测试启动阶段就会解析线程组的配置参数,而setUp线程组是在测试启动后才执行的。直接使用__P()或__Property()函数无法动态读取setUp线程组中后续设置的属性;另外,当存入props的是整数类型时,__Property函数默认返回字符串,可能存在类型不匹配导致的读取失败。
解决步骤
使用__groovy()函数动态读取属性
在常规线程组的「线程数」和「Ramp-Up时间」配置项中,分别使用以下表达式:- 线程数:
${__groovy(props.get("threads") as int,)} - Ramp-Up时间:
${__groovy(props.get("rampup") as int,)}__groovy()函数可以直接访问JMeter的props对象,并且能将属性值正确转换为整数类型,避免类型不匹配问题。
- 线程数:
可选:存入属性时转为字符串
如果偏好使用__Property()函数,可以在JSR223取样器中存入属性时将整数转为字符串:props.put("threads", String.valueOf(qty)); props.put("rampup", String.valueOf(qty));此时线程组配置中使用
${__Property(threads,1)}即可读取属性值(第二个参数是默认值),但__groovy()方式更可靠,能直接处理动态设置的属性。
验证方法
修改线程组配置后重新运行测试,查看JMeter日志,确认线程组启动时显示的线程数和Ramp-Up时间与预期一致。
内容的提问来源于stack exchange,提问作者forkintheass

