最近有小朋友经常问关联怎么做,正好遇到一个好的小实例,写下。
收益:
从一个小的测试实例中可以快速简单的了解到jmeter的一些使用技能,比如关联,正则表达式的使用,if控制器,jmeter作用域。
背景:
收到一个很简单的性能测试的需求:
压测下面页面: http://[ip地址]/test5?data=[加密数据][&sign][加密数据]
备注:【数据就不贴出来啦】
要求 60qps,页面5s内加载完 且观察涉及的几个服务的应用服务器的CPU、内存、IIS情况
脚本过程:
恩,需求和指标都很明确。于是我们手动点开看了下待测的页面:
发现有个跳转在中间一闪而过,用fiddler工具抓包看了下,其实是包含一个登录的操作。进一步找技术人员沟通得知,这是一个联合登录。
抓包
开始用badboy工具来录制请求。 我们发现和抓包一样的发现很多个请求,远远不止开始开发提测的一个get请求而已。
录制好请求后,把脚本保存为JMX格式,用jmeter打开。我们加了一个“查看结果树”调试器,点“开始”放了一遍。查看了下返回,发现都是其他的JS页面或者报错。
默默得打开了fiddler工具抓了个包。发现第一次请求的时候,服务返回的报文里面含一段 authcode=6F84F9C8976DA39F923A7B87D94AB25E
特别留意了下,于是第二次手动请求再抓包,发现这个authcode每次请求都会不一样。
接着往下找,发现这个authcode 在后面的登录请求里面是需要使用到的。
关联
于是我们此处需要一个关联:
我们在第一个请求前面, 后置处理器-->正则表达式提取器抓取了authcode码后,我们在登录的请求里面,用到的authcode码做成参数化,参数名 code,来抓取这个服务器返回的authcode。
正则1 参数化1
关联知识Tips:
方法一:从前一个请求中取,用正则表达式提取器。
具体方法,在需要获得数据的请求上右击添加一个后置处理器-->正则表达式提取器引用名 称即下一个请求要引用的参数名称,如上图的填写code,则可用{code}引用它. 正则表达式中()括起来的部分就是要提取的。其中.代表任意字符,*代表出现任意次。 模板,用$$引用起来,如果在正则表达式中有多个正则表达式(多个括号括起来的内 容),则可以是2,3$等等,表示解析到的第几个值给code。匹配数字,0代表随机,-1代 表所有,其余正整数代表将在检查的内容中,第几个匹配的内容提取出来。
JMeter做关联需要对业务熟悉,知道需要关联的数据是由哪个请求发送的,不知道的话用抓包工具比较下。一般来说,脚本录制好后,我们需要在“测试计划”级别下添加一个“监听器-查看结果树”。这个监听器是用来调试脚本使用的,有点类似于LoadRunner中的replay snapshot。在察看结果树中,我们可以看到每个请求的状态,发送的数据及响应数据。
这个时候,我们再请求调试一次,发现登录是成功。
抓包2但是,在登录下面的请求页面,也就是我们真正的待测页面,还是请求失败,服务器回给我的是一个看不懂的JS页面。
默默地继续抓包,发现这个请求里面要传递的数据确实都一样,就2个参数。一个data ,一个 sign 。 而且都是用固定的加密算法加密的。
参数2停下来思考下,是不是要带cookie啥的。
然后从抓包工具里面找到了很长的一段cookie
【省略一段】ctit=28D3B3C0E2B55D3CF6AE4FBE41718BB11D7B65C4E694A4643FB43704206CC9AE; 【省略一段】
然后我们把这段cookie,放在我们的HTTP信息头管理器里面。再一次点运行,返回的是我们的预期页面。成功了~
然后就结束了吗?NONONO。还是再请求了一笔,又抓了一个cookie
【省略一段】ctit=28D3B3C0E2B55D3CF6AE4FBE41718BB18F5E8A2972F2688BFC2EEC6C892AEFAC;【省略一段】
看起来和前面的好像一样,但仔细看了看,实际有个ctit= xxxxxxxx这一长串不一样。
于是,找到了开发小哥哥。
问了下逻辑。说是他们在请求登录接口后,登录接口会返回报文里面会带这个cticket的值,然后服务器会写下cookie值,然后呢,下次真正的请求把这个cookie带出去。每次这个cticket是不一样的。
验证了下我们的想法,要本地写cookie,开始想到了用beanshell,后面仔细想了下,因为格式都一样,只有一个字段不一样,是不是可以把这个字段存到变量里面。
于是又开始用正则表达式抓取。
正则2
再把 HTTP信息头管理器的那个cookie参数,其中的这个字段用参数化处理好;
到这里为止,我们发现待测的请求页面能够得到预期的返回了,但其中另外一个页面又返回不对了,在做这个步骤之前还是能够得到预期返回的。why?
作用域
经检查:我们开始把这个"HTTP信息头管理器" 放在了线程组的下面第一个的位置,它的作用域覆盖下面所有的请求。我们另外待测的请求和开始请求的一个请求,其实是一个相同的请求,但第一个请求只是为了获取一个登录接口的一个authcode码,而待压测的请求登录成功后,正常请求页面。如果把“HTTP信息头管理器 ” 放在所有请求前面,它就对所有的请求都作用,但我们只要对待测的请求生效,于是就把这个HTTP信息头管理器拖到了这个请求的前面。
作用域1
作用域知识tips:
在jmeter中,组件的作用域是靠测试计划的的树型结构中元件的父子关系来确定的,作用域的原则是:
逻辑控制器(Logic Controller):只对其子节点中的取样器 和 逻辑控制器作用。
对于6类基础任务组件,如果是某个sampler的子节点,则该组件只对其父子节点起作用。
对于6类基础任务组件,如果其父节点不是sampler ,则其作用域是该组件父节点下的其他所有后代节点(包括子节点,子节点的子节点等)。
到这里为止,我们模拟用户访问的请求都成功了,但我们实际只有登录成功的才去请求这个待测页面,没有登录成功的,就直接丢弃不处理了。
IF控制器
然后我们加个if判断
if控制器
LoginErrMsg 的参数是放在正则表达式里面,把登录后才能访问的页面放在这个if的控制器里面。
if控制器
前面我们还有一个,就是如果第一次请求,服务器给我authcode码后,我才去登录,如果没有给我authcode码,那我就不处理了。
同样的处理,我们在登录的前面加个if控制器。
if控制器
这里可以看到,我们第二个if 是要求放在第一个if下面的。而且所有的正则表达式,都要放在请求的上面。不然会抓取不到哟
逻辑控制器知识tips:
逻辑控制器(Controller)可以帮助用户控制JMeter的测试逻辑,特别是何时发送请求。 逻辑控制器可以改变其子测试元件的请求执行顺序。
逻辑控制器用于制定一个线程组内不同取样器的执行顺序。例如,你可以添加交替控制器 来在两个HTTP请求取样器之间交替 。更多信息详见5.3.2逻辑控制器。
逻辑控制器用于制定一个线程组内不同取样器的执行顺序。
逻辑控制器包括两类:
一类是用于控制测试计划中 sampler 节点发送请求的逻辑顺序的控制器,常用的有If控制器 、switch Controller 、Runtime Controller、循环控制器等。(详细如下)
另一类是用来组织可控制 sampler 来节点的,如事务控制器、吞吐量控制器。
最后,因为是测试一个页面,我们在被测页面的url加个随机参数,以防止缓存。
网友评论