一、背景
有这样的一个需求:需要压测注册接口,使用电话号码注册且电话号码不允许重复。如何编写压测脚本呢?
可以使用Jmeter自带的随机函数实现,但是这种方式在高并发压测的时候,随机出来的数值也是有一定的概率会重复的。
也可以使用BeanShell脚本前置生成随机的电话号码,处理时将电话号码分为前缀、中段值、后缀3部分,前缀使用随机数,中段值取通过当前的时间戳除数获取,后缀再使用随机数,这样前后两个随机因子,再加上中段值是到毫秒级别时间戳,重复的概率非常非常低了。
二、电话号码自增的方式实现
使用Jmeter自带的配置元件》计数器来实现,计数器可以指定起始值、最大值、递增值。这个方式非常简单,通过自增的方式让线程每次取的值都是递增后的值,有效避免了重复的问题。网上也有很多讲解计数器使用的文章也是这样写的。
但是这个方法只适用于单台jmeter做压测的时候,如果接口需要比较高的TPS,需要使用多台压力机执行分布式压测时,由于每台压力机都是共用的master机器上的jmx脚本,都是以同一个起始值递增,那么每台压力机通过计数器生成的值就会重复。
因此思考了一下解决方案:由于分布式压测时,数据文件每一台压力机都是使用的自己的数据文件,因此设计为csv data set config + 计数器 +BeanShell Preprocessor的方式,通过csv数据文件设置不同的第1位数,计数器生成后续10位数,然后通过BeanShell Preprocessor中的beanshell脚本组装成11位的电话号码。
这样压力机1的电话号码范围为:11000000000-19999999999,压力机2的电话号码范围为:21000000000-29999999999,只要每台压力机压测期间发出的请求数量不超出这个范围,就不会有重复。
csv data set config配置:
计数器.csv文件:
计数器配置元件:
启动(Starting value):给定计数器的起始值、初始值,第一次迭代时,会把该值赋给计数器
递增(Increment):每次迭代后,给计数器增加的值
最大值(Maximum value):计数器的最大值,如果超过最大值,重新设置为初始值(Start),默认的最大值为2^63-1
数字格式(Number format):可选格式,比如000,格式化为001,002;默认格式为Long.toString(),但是默认格式下,还是可以当作数字使用
引用名称(Reference Name):用于控制在其它元素中引用该值,引用形式:${reference_name}
与每用户独立的跟踪计数器(Track Counter Independently for each User):全局的计数器,如果不勾选,即全局的,比如线程#1 获取值为1,线程#2获取值就是递增后的值为2。
如果勾选,即独立的,则每个用户有自己的值:比如用户#1 获取值为1,用户#2获取值也为1
每次迭代复原计数器(Reset counter on each Thread Group Iteration):可选,仅勾选与每用户独立的跟踪计数器时可用。
比如线程数设置为2,循环次数设置为2:
不勾选“与每用户独立的跟踪计数器”,运行4次,则取值结果为:
勾选“与每用户独立的跟踪计数器”,运行4次,则取值结果为:
勾选“与每用户独立的跟踪计数器”+勾选“Reset counter on each Thread Group Iteration”, 则取值结果为:
BeanShell PreProcessor代码如下:
qianzui=vars.get("startvalue");
houzui=vars.get("phone");
String phone=qianzui.toString()+houzui.toString();
vars.put("phoneValue",phone);
log.info("电话号码的值为:"+vars.get("phoneValue"));
HTTP请求里面使用phoneValue变量:
以上就是本次的全部内容,如果对你有帮助,欢迎关注我的微信公众号:程序员杨叔,各类文章都会第一时间在上面发布,持续分享全栈测试知识干货,你的支持就是作者更新最大的动力~