【问题标题】:How do I pass a variable from one Thread Group to another in JMeter如何在 JMeter 中将变量从一个线程组传递到另一个线程组
【发布时间】:2010-10-17 00:12:31
【问题描述】:

我有一个带有 2 个线程组的 JMeter 测试 - 第一个是单个线程(创建一些库存),第二个是多个线程(购买所有库存)。我使用 BeanShell 断言和 XPath 提取器来解析返回的值(即 XML)并存储变量(例如要购买的商品的 id)。

但是,在第一个线程组中创建的值,无论是提取到标准${jmeter} 类型变量还是${__BeanShell(vars.get("jmeter"))} 类型变量中,都不能在第二个线程组中使用。无论如何要在第一个线程组中创建一个变量并使其对第二个线程组可见?

【问题讨论】:

    标签: java testing jmeter beanshell


    【解决方案1】:

    我无法对变量执行此操作(因为这些变量是单个线程的本地变量)。但是,我能够通过属性解决这个问题!

    同样,我的第一个 ThreadGroup 完成了所有设置,我需要从该工作中获取一些信息,以供第二个 ThreadGroup 中的每个线程使用。我在第一个 ThreadGroup 中有一个 BeanShell 断言,其中包含以下内容:

    ${__setProperty(storeid, ${storeid})};
    

    ${storeid} 是使用 XPath 提取器提取的。 BeanShell Assertion 执行其他操作,例如检查 storeid 是否从上一次调用返回,等等。

    无论如何,在第二个 ThreadGroup 中,我可以使用 Samplers 中“storeid”属性的值:

    ${__property(storeid)}
    

    像魅力一样工作!

    【讨论】:

    • 太糟糕的属性不能存储对象...实际上似乎 get()put() 方法仍然可以从 HashTable 获得。如果我滥用 jmeter 属性来存储对象值会不会很糟糕?我的问题是我希望所有线程共享同一个对象,以避免在使用大量线程运行时创建多个对象。
    • 这里有一个问题。在将脚本传递给 BeanShell 之前调用 __setProperty。因此,如果您尝试从 beanshell 为变量赋值,您将无法获取该值
    • @akostadinov,然后你就会遇到瓶颈,因为所有线程都在等待一个对象,并且任何时候只有一个对象可以触摸它。
    • @Pacerier,取决于用例。对于只读对象(或大多数只读对象),线程之间不需要同步,因此没有瓶颈。
    • @akostadinov 根据以下链接,您可以使用 getObject() 和 putObject() 并使用 use "bsh.shared" 共享命名空间来共享变量。 jmeter.apache.org/usermanual/best-practices.html#bsh_variables
    【解决方案2】:

    根据 JMeter 文档:

    16.12 在线程和线程组之间共享变量

    变量是线程本地的,无法读取在一个线程中设置的变量 其他。这是设计使然。对于可以确定的变量 在测试开始之前,请参阅参数化测试(上文)。如果值 直到测试开始才知道,有多种选择:

    1. 将变量存储为属性 - 属性对于 JMeter 实例
    2. 将变量写入文件并重新读取。
    3. 使用 bsh.shared 命名空间 - 请参阅 16.8.2 Sharing Variables
    4. 编写您自己的 Java 类

    在线程之间传递变量的另一种方法是使用 jmeter-plugins 作为mentioned by Andrey Botalov below

    但我发现第一次使用它有点令人困惑,但它可以在从线程传递到线程期间完全控制变量。 按照我的 BeanShell 使用示例,您会发现它是多么容易:

    接下来参考下图中的部分:

    (1.1) 在这里,我在用户定义变量中创建了自定义变量(或者您可以使用 BSF 处理器来实现 - 在本例 (1.2) 中禁用)

    (2.1)(2.4)我在第一个线程中成功使用了变量 - 没什么特别的:)

    (2.2)添加了BeanShell PostProcessor并自定义了我的变量

    (2.3)加入队列

    (3.1) 在第二个线程中 - 变量取自队列 - 使用您想要的任何名称。但是要小心,明智地使用超时,因为这个线程会一直等到前一次完成,所以它可以得到修改的变量(实验一些长响应)

    (3.2)(3.3)(3,4)重复使用和修改变量的步骤

    (3.5) 变量在新队列中再次发送 - 所以为其提供新名称

    (4.1)(4.2)(4.3) 从新队列中抓取修改后的变量就像魅力一样

    警告

    1. 如果您添加更多线程,然后将一些计数器添加到带有变量的线程组并将此变量名称添加到队列名称中 - 在您尝试捕获队列的线程组中执行相同操作,以便队列将为每个线程具有唯一名称(写一个如果您需要更清晰的解释,请发表评论)

    2. 如果您在一个线程组中有多个 http 请求,则添加线程通信预处理器作为 last 的子级(或其他,如果您想实现一些自定义的东西)http 请求

    播放、修改、自定义以获得最佳结果 :) 添加更多线程可能会导致不良行为,因此您需要保持警惕。

    【讨论】:

      【解决方案3】:

      我发现我认为这是完成这项工作的最简单方法。

      使用

      Bean Shell PostProcessor
      

      设置在一个线程组中

      设置变量(http://jmeter.apache.org/usermanual/best-practices.html#bsh_variables

      import org.apache.jmeter.util.JMeterUtils;
      JMeterUtils.setProperty("PC_CREATED_PROMO_CODE", "value");
      

      或者如果你想将它设置为另一个变量中包含的值

      import org.apache.jmeter.util.JMeterUtils;
      JMeterUtils.setProperty("PC_CREATED_PROMO_CODE", vars.get("Extracted_PC_CREATED_PROMO_CODE"));
      

      进入另一个线程组

      然后从另一个线程组,通过 (http://jmeter.apache.org/usermanual/functions.html#__property) 读取它

      ${__property(PC_CREATED_PROMO_CODE)}
      

      【讨论】:

        【解决方案4】:

        JMeter 插件有 Inter-Thread Communication 用于此目的。

        有两种使用方法:

        • 后处理器/预处理器
        • 函数__fifoPut__fifoPop

        在我看来 PostProcessor/PreProcessor 更容易使用。

        【讨论】:

        • 我更喜欢接受的答案的原因是我发现如果我使用线程间通信方法,我只能“弹出”队列一次并在单个采样器中使用该值。也许我做错了,但我必须将预处理器放在给定的采样器(HTTP 请求)中,如果该采样器处于循环中,它只会在尝试读取队列超时之前工作一次。
        • @Joe 根据线程间通信的文档,这是预期的行为。如果您想多次使用放入 FIFO 队列的变量,我认为您可以将 ${__fifoPop(queue_name, var_name)} 分配给 User Parameters 预处理器中的线程局部变量
        • @AndreyBotalov,这个解决方案可靠吗?线程有时会做一些奇怪的事情,例如一个线程可能会在其他线程运行时延迟几分钟。 ITC插件遇到这种情况会有问题吗?
        【解决方案5】:

        只需添加一个 bean shell 断言,使用属性函数将值分配给一个变量(如全局变量),即使在它进入其他线程后也会保存该值。

        线程组 >> 添加 >> 断言 >> Bean Shell 断言

        ${__setProperty(Global_variable_Name,${Variable_name_whose_Value_to_be_Passed})}
        

        然后在另一个线程中你可以调用这个全局变量并可以使用它

        下面是调用存储值需要用到的函数:

        ${__property(global_variable_name)}
        

        https://medium.com/@priyank.it/jmeter-passing-variables-between-threads-a4dc09903b59

        【讨论】:

        • 感谢您的回答。我建议对其进行一些重新格式化。一般来说,请记住,将! 放在图像前面将允许您将其置于内联。另外,建议使用正式语言而不是互联网速记(即:“you” vs. “u”)。
        【解决方案6】:

        这在 JMeter 中是不可能的,因为这不是正常的客户端行为(线程之间共享参数)。而不是使用一个带有控制器的线程组:

        Thread Group
        + Create inventory
        + + XPath
        + Loop
        + + Purchase inventory
        

        【讨论】:

        • 对于重要的测试用例,使用逻辑控制器很快就会变得非常乏味(到无法使用的地步)。
        【解决方案7】:

        嗯,这是一种方法;按照这些步骤操作,它会起作用,稍后您可以根据需要进行调整!变量不在线程之间共享(JMeter 可能将此称为功能:))。但属性是!所以将你的变量设置为这样的属性:

        1) 单击您的测试计划并启用“连续运行线程组”-> 这使得线程组按顺序运行,而不是随机运行。 (你可以稍后调整它,但现在让它工作..)

        2) 例如创建一个名为“setup”的线程组;在该线程组中添加一个 BeanShell 采样器,代码如下:

        import org.apache.jmeter.util.JMeterUtils;
        JMeterUtils.setProperty("theNameOfYourNewProperty", "theValueOfYourPropery");
        

        所以现在属性已经设置好了!如果您要存储为属性的值是一个变量(例如用户定义的变量或 reqex 变量),您可以这样做:

        JMeterUtils.setProperty("theNameOfYourNewProperty", vars.get("theNameOfYourVariable"));
        

        3) 添加一个测试组“实际测试”,例如线程数大于 1; 添加一个测试,然后在该测试中添加一个 BeanShell 预处理器,代码如下:

        import org.apache.jmeter.util.JMeterUtils;
        vars.put("theNameOfYourNewProperty", JMeterUtils.getProperty("theNameOfYourNewProperty"));
        

        现在您已经在该线程中创建了一个名为 theNameOfYourNewProperty 的变量,该变量具有您的系统属性 theNameOfYourNewProperty 的值。在您的测试中,您现在可以像这样访问它:

        ${theNameOfYourNewProperty}
        

        它适用于每个线程,而不仅仅是第一个线程..

        【讨论】:

          【解决方案8】:

          让主题重获新生 :) 在线程之间传输变量的另一种方法是写入/读取文件。 Passing variables between threads

          【讨论】:

            【解决方案9】:

            另一个解决方案是使用简单表服务器来管理数据集。 此功能是添加 1.2 JMeter 插件。

            “主要思想是在 JMeter Plugins 中使用一个微型 http 服务器来管理数据集文件,通过简单的命令来get / add 文件中的数据行”

            查看文档: http://jmeter-plugins.org/wiki/HttpSimpleTableServer/

            问候。

            【讨论】:

            • 嗯,不使用HTTP做代理,为什么不直接连接数据库呢?
            【解决方案10】:

            我使用 set property 函数和 teardown teardowngroup 从 setupthreadgroup 获取值,但 teardown threadgroup 得到 401 错误。

            我检查了所有标题,一切看起来都很好。不确定你的拆卸失败。 有什么想法请给我建议

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-11-21
              • 2011-04-27
              • 2019-09-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多