我正试图在同一线程组中的多个线程之间执行setproperty,后处理器使用setproperty设置新变量,以便可以在多个线程中访问它。
在Beanshell预处理器中,我有下面的代码行。
${__setProperty("url","youtube"(};
在线程组下,我有Beanshell后处理器,在后处理器中只有一行。
${__setProperty("url","google"(};
在线程组下,我有HttpSampler,在主机名字段中,我给出了${__property(url(}.com
目标是,当它第一次执行时,URL将是google.com,当第一个线程完成时URL变为youtube.com但是setProperty只设置了google,后处理器中的第二个不起作用。
有关详细信息,请参阅下图,它显示了我是如何在Jmeter中创建元素的。
在此处输入图像描述
注意:这只是一个示例用例,但我有一个复杂的例子,但回答这个问题将帮助我在复杂的脚本中添加逻辑。
感谢
那么,第一个完成的线程的目标是更改所有后续创建的线程的URL吗?
我对文档的理解是,您不能更改线程组内属性的值:Properties can be referenced in test plans - see Functions - read a property - but cannot be used for thread-specific values.
(参见http://jmeter.apache.org/usermanual/test_plan.html#properties)
我的假设是,线程组中的每个线程都会获得属性的副本。如果更改线程组内属性的值,那么实际上就是在更改该特定线程的副本。由于您在后处理器中对其进行更改,线程很可能即将被处理,导致您的更改丢失。处置后,将创建一个新线程,但使用该属性的原始值。
因此,您需要做的是找出如何在线程组之外更改值。
我在自己的测试中也做过类似的事情,即在测试过程中更改属性的值,所有活动的线程组都会立即获取该值,从而使从那时起创建的每个新线程都获得新值。我使用Beanshell服务器来完成此操作:https://jmeter.apache.org/usermanual/best-practices.html#beanshell_server
在我的特定情况下,我使用jenkins作业,该作业调用一个连接到本地主机上运行的beanshell服务的shell脚本:
java -jar ${jmeter_home}/apache-jmeter-5.0/lib/bshclient.jar localhost 9000 ${test_plan_home}/update_Prop.bsh "${property}" "${value}"
我的update_prop.bash文件就是:
import org.apache.jmeter.util.JMeterUtils;
JMeterUtils.getJMeterProperties().setProperty(args[0],args[1]);
不过,您不需要使用Jenkins或类似的东西——如果您将JMeter进程设置为包含Beanshell服务器(请参阅上面的链接(,那么您可以简单地替换后处理器中的代码:${__setProperty("url", "google")};
使用连接到beanshell服务器并在那里执行命令的代码:exec("./updateprop.bash url google");
- JMeter属性是全局,因此一旦设置了属性,它就可用于所有线程
-
每个JMeter线程(虚拟用户(都执行采样器。预处理器和后处理器都遵守JMeter范围界定规则查看您的测试计划,执行顺序如下:
- Beanshell预处理器
- HTTP请求采样器
-
Beanshell后处理器
因此,HTTP请求采样器将永远不会命中
youtube
(除非您由于并发而遇到竞争条件(,因为预处理器将把URL设置回google
-
自JMeter 3.1 以来,建议使用JSR223测试元素和Groovy语言进行脚本编写
-
不建议将JMeter函数和/或变量内联到脚本中,您需要使用"参数"部分或使用基于代码的等效项,因此需要替换此行:
${__setProperty("url", "youtube")};
这个:
props.put("url", "youtube");