正则表达式提取变量
设置一个变量名,假如为 token
- 如果正则只用提取一组数据,且正则只匹配到了一个,我们直接使用
${token}
即可正常提取数据,${token_g0}
表示把正则中除小阔号之外的字符串也写了进来,这个写法在下面可以类比使用 - 如果正则只用提取一组数据,但是可以匹配多个,我们使用
${token_1}
,${token_2}
…的形式来匹配提取到的整个数组的数据,${token_g}
表示提取一共有多少个被正则匹配了的数据 - 如果正则要提取两组数据,正则只匹配到了一次,我们可以使用
${token_g1}
和${token_g2}
来提取两组数据 - 如果正则要提取两组数据,正则可以匹配到多次,我们可以使用
${token_1_g1}
,${token_2_g1}
…和${token_1_g2}
,${token_2_g2}
…的形式来提取各组中第几个匹配到的数据,且要注意的是${token_2_g1}
可不能写成${token_g1_2}
,一定要把第几个写在前面,把第几组写在后头!
${xxx}
的形式不是字符串!若要让其成为字符串,需要外面加上""
即可
beanshell 中的变量
拥有内置变量,如 vars 和 props,在 beanshell 中 put 的变量在其他控件中也可使用,如${a}
这种形式就可以取用
vars
我们通常会使用 vars 来存储变量和提取变量,但是值得注意的是 vars 只能在一个线程组内传递,我们看下面的例子
vars.get("token_1_g1");
vars.put("a", "1");
这个写法是没有问题的,其传参接收字符串,如果直接写token_1_g1
没有被双引号包裹是会报错的,准确是来说${token_1_g1}
正则拿到的是一个值,而不是字符串类型参数。put 方法第二个参数必须也是字符串!
vars put 之后在当前线程其他控件也是可以使用的,不是说非要局限于 beanshell 中,在其他控件中可以通过${a}
的形式取用
有个非常奇葩的点是,在 beanshell 中使用了 vars 的 put 方法,则在该 beanshell 只能通过 vars get 方法拿到,不能通过美元符取到,但是却可以在该 beanshell 外部通过美元符拿到,目前还不知道原因
props
属性的存储,与 vars 非常类似,但是 props 是在整个计划内都是有效的,也就是可以跨线程,整个注意与 vars 区别
同样也是 get 和 put 方法
我们可以在 jmeter【测试计划】->【添加非测试元件】->【属性展示】看到各种属性
jmeter 内置函数操作变量
jmeter 的内置函数在整个 jmeter 控件中是通用的,不限于 beanshell!
有时候正则提取的数据如${token_1_g1}
可以拿到,对于一些简单的请求器(非 beanshell)就无法使用 vars 和 props 了,假如在简单请求器中想将其设置为跨线程全局属性,我们可以利用 jmeter 函数
函数手册请见 jmeter 工具内
// 存储为属性,参数一表示变量名,参数二表示变量值,参数三表示默认值
${__setProperty(token_1_g1,${token_1_g1},0)}
// 取出属性值
${__property(token_1_g1)}
变量结合 foreach 使用
foreach 循环控制器允许循环遍历,传入的变量前缀常常可以在正则中拿到,如果想在 beanshell 中拿到,那么在 beanshell 中需要 put 进去a_1
值为"1"
很可惜 foreach 只能接收一个变量前缀名
关于变量的嵌套
我们在写 beanshell 时候难免会遇到变量嵌套的情况
情景一:一个为美元符,一个为刚刚声明的变量
当我们使用正则提取器提取了数据之后,我们可以在其他控制器中通过这种方式来使用变量${token_1_g1}
,${token_2_g2}
这个 1,2…在 beanshell 中可以写一个 for 循环将其中的 index 传过去,这样我们该如何变量组合嵌套呢
首先错误的形式是${token_index_g1}
和"${token_"+i+"_g1}"
这两种方式都不行,并且 beanshell 中 vars put 的变量,在该 beanshell 中还不能用美元符去取用,put 之后可以在其他控件中使用,甚至是下一个 beanshell 中使用
log.info(vars.get("token_"+i+"_g1"));
情景二:两个都为美元符可提取的变量
可以使用 jmeter 内置函数,__V()
目前变量不支持嵌套,如${Var${N}}
不能正常工作,但是Jmeter2.2以后可以通过__V (variable)
来实现,比如${__V(Var${N})}
再比如说有两个变量preSaleId和变量counter,比如说要${preSaleId_${counter}}
提取的东西,实际上jmeter是不支持这种形式的,但可以用${__V(preSaleId_${counter})}
形式成功提取
值得注意的点
值得注意的是不论是 jmeter 内置函数的使用还是正则提取数据的形式都是不带双引号的,而且提取的数据如果要识别为字符串还需自己加上双引号
而 beanshell 好歹也是支持 java 语言,所以 vars 和 props 需要给变量加上双引号!
beanshell 中 vars put 的变量不能在该 beanshell 中通过美元符取出,但是可以在后续其他控制器中通过美元符取出
当变量嵌套时候想要取值,可以使用__V
的内置函数等
还有在 beanshell 中通过美元符提取数据是默认整型,所以当提取的数很大时候,可能会报出数字范围超限的 error,所以可以这么做int a = "${value}"
这样是可以识别的,但是在 beanshell 内置变量中如vars.put("a", "${value}")
就会有问题,它会把${value}
当成一个字符串,换句话说,beanshell 内置变量中的传参时无法识别美元符的,只有 beanshell 里头才能识别美元符
那些不可以做的事
不能做的事:
正则提取的数据我们通过,${变量名_matchNr}
这种形式就可以拿到正则提取了多个,即使正则用了多个模板,比如mid_1_g1
还有mid_1_g2
使用${mid_matchNr}
得到的数值是 1,如果我们在 beanshell 中改一下,通过 vars 添加,比如下面
vars.put("mid_2_g1");
vars.put("mid_2_g2");
log.info(vars.get("mid_matchNr"));
输出的会是 2 吗,很可惜,还是 1,mid_matchNr 只会匹配正则中提取了几个,beanshell 中的改动不能影响
不能做的事:
在 beanshell put 变量之后,不能在当前 beanshell 中使用美元符将变量取出,但是可以在该 beanshell 之后的元件中使用美元符取出,不管后序的是不是 beanshell 处理
不能做的事:
beanshell 中内置变量中不能加上${变量_num}
的形式,如下面写法都会报错
vars.put(${token});
vars.put("a", ""+${token});
log.info(""+${token})
log.info(${token})
log.info("${token}");
要注意的是前四种都会报错 error,内置变量必须接收字符串参数,第五种不会报 error 但是失去了意义,直接打印"${token}"这样的字符串了