JMeter:如何在For Each Controller下重置计数器?
嘿,我来帮你搞定这个计数器重置的问题!你现在的场景是For Each Controller遍历一组数据,每次迭代里跑JDBC请求和Beanshell断言,断言里用__counter函数给value1赋值,但希望每次新的For Each循环启动时计数器能回到1,而不是一直往上涨对吧?
默认的__counter函数是线程级或者全局的,没办法自动在For Each的每次循环组前重置,所以我们需要手动控制计数器的生命周期,这里有几个靠谱的方案:
方案1:用自定义变量手动管理计数器(最直观)
这个方法的核心是:在For Each Controller开始前重置计数器,然后在每次断言里手动递增。
添加重置步骤:在For Each Controller的直接上方,加一个
JSR223 PreProcessor(或者Test Action元件里加Beanshell代码),把计数器变量重置为1:// 重置自定义计数器为1 vars.put("my_custom_counter", "1");(注:如果你还在用旧版JMeter,用Beanshell PreProcessor也可以,代码一样)
修改Beanshell断言代码:把原来用
__counter的逻辑换成手动读取、赋值、递增自定义变量:// 获取当前计数器值 int currentCounter = Integer.parseInt(vars.get("my_custom_counter")); // 给value1赋值 vars.put("value1", String.valueOf(currentCounter)); // 计数器加1,供下一次迭代使用 vars.put("my_custom_counter", String.valueOf(currentCounter + 1));
这样一来,每次For Each Controller开始遍历新的变量组时,计数器都会先被重置为1,然后在每一次迭代里递增,完美符合你的需求。
方案2:用JSR223断言替代Beanshell(推荐,性能更好)
如果你用的是JMeter 3.1及以上版本,官方更推荐用JSR223元件(比如JSR223 Assertion)代替Beanshell,因为Groovy引擎性能更高,语法也更灵活。
同样在For Each前加
JSR223 PreProcessor重置计数器:vars.put("my_custom_counter", "1");JSR223断言里的代码:
def counter = vars.get("my_custom_counter") as int vars.put("value1", counter.toString()) vars.put("my_custom_counter", (counter + 1).toString())
为什么不用__counter直接重置?
__counter函数本身有个per_user参数(比如__counter(TRUE)),但它的重置逻辑是每个线程(虚拟用户)启动时重置,而不是每次For Each循环组启动时重置。所以如果你的For Each是在同一个线程里多次执行,这个参数帮不到你,还是得用自定义变量的方式来精准控制重置时机。
最后提醒一下:如果你的For Each Controller还嵌套在其他循环控制器里,记得把重置计数器的步骤放在最靠近For Each的父级循环的前置位置,确保每次For Each启动前都能触发重置。
内容的提问来源于stack exchange,提问作者Preeti

