Jmeter${__setProperty()}无法跨同一线程组中的多个线程工作



我正试图在同一线程组中的多个线程之间执行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");

  1. JMeter属性是全局,因此一旦设置了属性,它就可用于所有线程
  2. 每个JMeter线程(虚拟用户(都执行采样器。预处理器和后处理器都遵守JMeter范围界定规则查看您的测试计划,执行顺序如下:

    1. Beanshell预处理器
    2. HTTP请求采样器
    3. Beanshell后处理器

      因此,HTTP请求采样器将永远不会命中youtube(除非您由于并发而遇到竞争条件(,因为预处理器将把URL设置回google

  3. 自JMeter 3.1 以来,建议使用JSR223测试元素和Groovy语言进行脚本编写

  4. 不建议将JMeter函数和/或变量内联到脚本中,您需要使用"参数"部分或使用基于代码的等效项,因此需要替换此行:

    ${__setProperty("url", "youtube")};
    

    这个:

    props.put("url", "youtube");
    

相关内容

最新更新