1.1 关联
1.1.1 什么是关联
所谓的关联(correlation)就是把脚本中某些写死的(hard-coded)数据,转变成是撷取自服务器发送的、动态的、每次都不一样的数据。在脚本回放过程中,客户端发出请求,通过关联函数所定义的左右边界值(也就是关联规则),在服务器所响应的内容中查找,得到相应的值,以变量的形式替换录制时的静态值,从而向服务器发出正确的请求,这种动态获得服务器响应内容的方法被称作关联。其实关联也属于一种特殊的参数化,只是与一般的参数化有些不同。一般的参数化的参数来源于一个文件、一个定义的table、通过sql写的一个结果集等,但关联所获得的参数是服务器响应请求所返回的一个符合条件的、动态的值。
例如:我们去坐飞机,登机之前要检票(机票信息相对固定),通过可以登机。过了几天拿着同一机票再去登机,自然不能登机(机票信息已过期)。那怎样才能顺利登机?可以伪造机票信息…这里我们通过收集别人返回的信息(机票)伪造机票,从而满足登机的验证策略。在脚本中也有类似的情况
1.1.2 为什么要关联
LR录制的脚本只是忠实记录了所有从客户端发送到服务器端的数据,并在脚本回放的时候按照录制的顺序将录制下来的数据重新发送出去。但是,实际上许多的系统都采用SessionID或SeqID等方法来标识不同的任务和数据包,应用在每次运行时发送的数据并不完全相同。所以,为了让脚本能够支持测试的需求,就必然要用某种机制对脚本的数据进行出来了。总之一句话:通过关联可以在测试中保持动态值。
当录制脚本时,VuGen会拦截client端(浏览器)与server端(网站服务器)之间的对话,并且通通记录下来,产生脚本。在VuGen的Recording Log中,您可以找到浏览器与服务器之间所有的对话,包含通讯内容、日期、时间、浏览器的请求、服务器的响应内容等等。脚本和Recording Log最大的差别在于,脚本只记录了client端要对server端所说的话,而Recording Log则是完整纪录二者的对话。
当执行脚本时,您可以把VuGen想象成是一个演员,它伪装成浏览器,然后根据脚本,把当初真的浏览器所说过的话,再对网站伺服器重新说一遍,VuGen企图骗过服务器,让服务器以为它就是当初的浏览器,然后把网站内容传送给VuGen。
所以纪录在脚本中要跟服务器所说的话,完全与当初录制时所说的一样,是写死的(hard-coded)。这样的作法在遇到有些比较聪明的服务器时,还是会失效。这时就需要透过「关联(correlation)」的做法来让VuGen可以再次成功地骗过服务器。
举一个常见的例子,刚刚提到有些比较聪明的服务器,这些服务器在每个浏览器第一次跟它要数据时,都会在数据中夹带一个唯一的辨识码,接下来就会利用这个辨识码来辨识跟它要数据的是不是同一个浏览器。一般称这个辨识码为Session ID。对于每个新的交易,服务器都会产生新的Session ID给浏览器。这也就是为什么执行脚本会失败的原因,因为VuGen还是用旧的Session ID向服务器要数据,服务器会发现这个Session ID是失效的或是它根本不认识这个Session ID,当然就不会传送正确的网页数据给VuGen了。
下面的图示说明了这样的情形:
当录制脚本时,浏览器送出网页A的请求,服务器将网页A的内容传送给浏览器,并且夹带了一个ID=123的数据,当浏览器再送出网页B的情求时,这时就要用到ID=123的数据,服务器才会认为这是合法的请求,并且把网页B的内容送回给浏览器。
在执行脚本时会发生什么状况?浏览器再送出网页B的请求时,用的还是当初录制的ID=123的数据,而不是用服务器新给的ID=456,整个脚本的执行就会失败。
201608261472142763497261.jpg LR脚本开发之参数化之关联 Tester 第2张
要对付这种服务器,我们必须想办法找出这个Session ID到底是什么、位于何处,然后把它撷取下来,放到某个参数中,并且取代掉脚本中有用到Session ID的部分,这样就可以成功骗过服务器,正确地完成整个交易了。
1.1.3 何时关联
- 登陆操作
- 业务需要(即后面的操作需要用到前面服务器返回的动态数据)
- 情况一
- 情况二
- 情况三
1.1.4 如何关联
1.1.4.1 关联的一般步骤
-
从服务器返回的数据中选取需要进行关联的数据,界定他的左边界和右边界
举例:
201608261472142763938685.jpg LR脚本开发之参数化之关联 Tester 第3张
查看服务器返回信息发现:8a3c341d5252c1a8015252d205470001是需要进行关联的值,则开始设置这个值的左右边界,左边界:resultObject":" ;右边界:"
注意:左边界和右边界要有独特性,能让系统直接定位到8a3c341d5252c1a8015252d205470001值,而不是定位到其他数值 - 将该数据存入脚本的一个参数中
- 将脚本中需要使用该数据的地方用参数来替换。
Tip:对于web来说,一般会用一个hidden 的 field存放。所以可以在服务器返回的记录查找该字段值。
1.1.4.2 手动关联
1.1.4.2.1 手动关联原理
手动关联是关联应用中的最有效手段,通过手动关联函数 web_reg_save_param()将想要的字符串保存到一个参数中。
1.1.4.2.2 手动关联的注意事项
web_reg_save_param函数一定要放在获取服务器返回值的请求前面,中间不能有其他的脚本,否则,将会获取不到服务器返回值,如示例所示。
如要输出服务器返回值,也只能在请求的后面输出,不能放在请求的前面。
web_reg_save_param("TfFarmerDraftId",
"LB=farmerDraftId:"", "RB="", LAST ); ;
web_custom_request("tfFarmerDraftManager.getTfFarmerDraftById.dwr_2",
"URL=http://10.188.180.231/tlcr/dwr/call/plaincall/tfFarmerDraftManager.getTfFarmerDraftById.dwr",
"Method=POST",
"Resource=0",
"RecContentType=text/javascript",
"Referer=http://10.188.180.231/tlcr/tfFarmerDrafts.do?method=draftNormalFarmer&bsm=false",
"Snapshot=t175.inf",
"Mode=HTML",
"EncType=text/plain",
"Body=callCount=1\npage=/tlcr/tfFarmerDrafts.do?method=draftNormalFarmer&bsm=false\nhttpSessionId=\nscriptSessionId=529CFA712B612149367BF8EE3F9CB8A6615\nc0-scriptName=tfFarmerDraftManager\nc0-methodName=getTfFarmerDraftById\nc0-id=0\nc0-param0=string:8a3c34673ac05aad013ad87a93d00013\nbatchId=22\n",
LAST);
lr_error_message("TfFarmerDraftId: %s",lr_eval_string("{TfFarmerDraftId}"));
1.1.4.3 关联函数说明
1.1.5 FAQ
网友评论