java多窗口关联,3.7 关联 - AJava

3.7  关联

3.7.1  关联原理

先来模拟一个场景:我们去坐飞机,登机前需要在检票点出示机票,检票登机。那么检票人员会检查哪些东西呢?机票是否真实、航班是否正确等信息,验证通过即可登机。

过了几天我们又去坐飞机,还是拿同样的一张票去登机,检票人员再一次核对信息,发现机票已经过期了,自然就不能成功登机了,那怎么才能顺利登机呢?可以通过伪造机票信息的方式来登机,首先去询问其他乘客的机票信息,然后将自己的机票涂改为他们的机票,最后使用涂改后的机票登机。

在这里我们通过收集别人返回的信息,将提交给检票人员的数据修改为这些收集到的信息,从而满足登机的验证策略。在脚本中也存在大量类似的情况,录制的时候,服务器会给一个唯一的认证码来进行操作,当再次回放脚本的时候服务器会给一个全新的认证码,而脚本录制是死的,还是拿老的认证码提交,从而导致脚本执行失败。

例如:常见系统中的登录功能,在登录后服务器会返回SessionID,登录后的操作都需要提交该SessionID确认身份。使用VuGen录制时,将会记录服务器返回的SessionID并且原封不动地在下一个请求中发给服务器,如图3.127所示。

5092135_1.gif

图3.127  录制得到SessionlD

待到回放的时候,服务器会在接收到用户名和密码后返回新的SessionID,而脚本仍然发送旧的SessionID给服务器,最终因SessionID错误,导致脚本回放失败,如图3.128所示。

5092135_2.gif

图3.128  回放时SessionID 错误

为了确保脚本回放的成功,我们需要获得服务器每次返回的动态SessionID,再将这个动态数据发回给服务器。而关联能够帮助我们将服务器返回的数据进行处理并保存为参数。

如何获得服务器的返回数据呢?我们先来回顾一下VuGen是如何发出请求并如何接受返回数据的。录制一个Mspetshop访问首页的代码,看一下发出的请求和服务器的返回是什么。根据HTTP规范,应该是给服务器发了一个Get请求,服务器返回HTML页面。录制完成后把脚本切换到Tree模式,如图3.129所示。

在Tree模式下切换到web_url()函数,如图3.130所示。

5092135_3.jpg          

5092135_4.jpg

图3.129  切换视图为Tree模式         图3.130  Tree视图下选择:localhost:8081函数

在右侧的Snapshot中可以看到该请求对应的Page View,如图3.131所示。

5092135_5.jpg

图3.131  Tree视图下Url:localhost:8081函数Page View

在Page View的右侧就是客户端发给服务器的数据包Client Request,如图3.132所示。

5092135_6.jpg

图3.132  Tree视图下函数Client Request

服务器返回的Server Response数据内容也会被显示出来,如图3.133所示。

5092135_7.jpg

图3.133  Tree视图下函数Server Response

关联的作用是能够把服务器返回的Server Response内容保存为参数。关联是通过关联web_reg_ save_param()函数来实现的,这个函数可以帮助我们完成对服务器返回的保存操作。

现在将关联函数添加在脚本中。

Action()

{

//在请求前添加关联函数

web_url("localhost:8081", "URL=http://localhost:8081/", LAST);

return 0;

}

关联函数是一个注册型函数,需要告诉VuGen下一个请求返回是需要被处理的,所以该函数必须要写在请求前,否则就会提示无法获得关联结果的错误。这是绝大多数使用关联的新手最容易犯的错误。

将鼠标移动到添加关联函数的地方,然后选择Insert菜单下的New Step选项,如图3.134所示。

系统弹出Add Step窗口,在Find Function中输入web_reg_save_param找到该函数,如图3.135所示。

5092135_8.jpg 

5092135_9.jpg

图3.134  在代码中添加一个新步骤              图3.135  在Add Step中找到关联函数

确定后弹出web_reg_save_param关联函数设置窗口,如图3.136所示。

我们先不解释各个选项的作用,按照以下规则填写,如图3.137所示。

5092135_10.jpg  

5092135_11.jpg

图3.136  关联函数设置窗口                图3.137  设置关联服务器返回的所有内容

设置Parameter Name为temp,Instance为1,Search in为All,单击OK按钮,脚本变为下面的内容。

Action()

{

web_reg_save_param("temp",

"LB=",

"RB=",

"Ord=1",

"Search=All",

LAST);

//在请求前添加关联函数

web_url("localhost:8081", "URL=http://localhost:8081/", LAST);

return 0;

}

关联函数的作用是通过一种规则将服务器的返回保存到一个参数中,所以为了看到参数的内容,应打开参数取值的日志选项。运行脚本查看日志,会看到大量的蓝色参数值罗列出来,如图3.138所示。为了方便浏览,也可以打开该日志文件output.txt查看明细。

5092135_12.jpg

图3.138  关联后服务器返回的参数内容

每一句“Notify:Saving Parameter temp=”后面都是被关联到的服务器返回,我们会发现返回不止一条,一共有10次关联值被保存到了temp这个参数中去。那么访问一个页面怎么会有那么多个关联值呢?

根据对日志的具体分析会发现,被关联到的内容有以下几种:

1.HTML

2.CSS

3.JavaScript

4.JPEG、PNG、GIF

回想和对比一下前面介绍的HTTP基础,能够发现访问一个页面,服务器会先返回页面HTML,再下载页面中调用的CSS、JavaScript和图片,而关联函数把这些内容都抓了下来,所以会得到如此多的关联内容,也就是说通过这个关联函数获得了服务器所有的返回内容。

对于图片和CSS等内容其实一般都不是我们关心的,系统的动态数据需要关联的服务器返回信息一般都保存在HTML正文中。所以接着修改一下关联函数,将Search In选项从All修改为Noresource,也就是只需要关联HTML、XML等资源而不关联附属的信息。关联函数变为如下形式:

web_reg_save_param("temp",

"LB=",

"RB=",

"Ord=1",

"Search=Noresource",

LAST);

再运行一次可以看到被关联的内容只有一个了,而且就是服务器返回的HTTP包中的正文内容,和通过VuGen看到的服务器返回内容完全相同,现在这个返回是保存在一个叫做temp的参数中。

整个HTTP请求分为两段,一段是开头的HTTP头数据包,叫做header;另外一段就是HTML页面,叫做body。在“Search”选项中可以修改为Headers或者Body来更加精确地划分关联范围。

通常我们还是使用Noresource来处理关联范围,因为这样可以得到最常用的返回内容。在得到了服务器返回的内容后,接着就可以做任何想做的事情,比如获得页面中的任意一个对象,例如如何将MS Petshop 4.0首页上Powered by的字样抓出来作为参数呢?

关联函数提供了一个叫做左边界、右边界的策略,只需要填写这个规则,它会在整个被关联范围内查找符合该规则的内容。先查看需要关联的内容的对应代码。

Version 4.0 - Powered by .NET 2.0

在服务器返回的内容中,可以找到Powered by这个词,那么什么样的边界条件能够让我们获取这个词呢?可以通过设置左边界为 Version 4.0 -,右边界为.NET 2.0的方式来检索这个词,然后修改关联函数。

修改关联函数有以下两种方法:

1.直接在代码上修改。

2.切换到Tree模式下,双击关联函数,在Left Boundary/Right Boundary中输入条件,修改关联函数,如图3.139所示。

5092135_13.jpg

图3.139  修改关联函数的左右边界

确认后得到新的关联函数:

web_reg_save_param("temp",

"LB=Version 4.0 -",

"RB=.NET 2.0",

"Ord=1",

"Search=NoResource",

LAST);

现在再运行一下整个脚本,在日志中可以看到想要的这个词被成功地关联出来,并且保存到了参数temp中。

Action.c(20): Notify: Saving Parameter "temp =  Powered by "

可以通过lr_eval_string()将temp值提取出来并输出,或者提供给后面需要使用该值的函数。关联函数的结果需要请求结束后才能获得,所以提取关联结果参数的值必须在请求后,而关联函数必须在请求前。

由于我们在访问请求前设置规则,服务器返回的动态内容都会被关联函数捕捉并且保存到参数中,这样就实现了对动态数据的捕获,通过后期处理过程,即可完成对于动态对象的操作功能。

通常情况下我们使用关联的步骤流程如图3.140所示。

5092135_14.gif

图3.140  关联步骤流程

简单地说,关联就是对服务器的返回做处理的过程,刚才我们使用的是手动关联,而关联其实有3种方式:

1.自动关联

2.手动关联

3.一边录制一边关联

3.7.2  自动关联

首先来看最简单的自动关联。

自动关联是VuGen提供的自动扫描关联处理策略,它的原理是对同一个脚本运行和录制时的服务器返回进行比较,来自动查找变化的部分,并且提示是否生成关联。

打开LoadRunner自带的Web Tours网站,录制一个登录的过程然后再回放,通过Test Results界面可以看到回放虽然没有提示错误,但是并没有正确地登录到系统,如图3.141所示。

5092135_15.jpg

图3.141  Web Tours登录脚本回放失败

问题就出在脚本中web_submit_data()函数的userSession(这里如果使用web_submit_ form()函数就不会出现错误,需要修改录制选项中的Recording等级和录制方式)。

web_submit_data("login.pl",

"Action=http://127.0.0.1:1080/WebTours/login.pl",

"Method=POST",

"TargetFrame=body",

"RecContentType=text/html",

"Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",

"Snapshot=t2.inf",

"Mode=HTML",

ITEMDATA,

"Name=userSession", "Value=98852.6810044552fAitHDtpHHQVzzzHDAfAipt

AizHf", ENDITEM,

"Name=username", "Value=admin", ENDITEM,

"Name=password", "Value=admin", ENDITEM,

"Name=JSFormSubmit", "Value=off", ENDITEM,

"Name=login.x", "Value=0", ENDITEM,

"Name=login.y", "Value=0", ENDITEM,

LAST);

这里的 userSession是用户在每次访问该网站时系统提供的随机字符串,用来区分不同的用户,在回放时由于发送了过期的userSession导致脚本回放失败。几乎绝大多数脚本回放失败都是因为关联的问题。现在单击Vuser菜单中的Scan Script for Correlations选项,如图3.142所示。

使用自动关联前,脚本必须要先运行一次。

运行后会在窗口中看到以下内容,VuGen已经识别出脚本中的动态内容,如图3.143所示。

5092135_16.jpg

图3.143  VuGen识别到可以自动关联动态数据

如果支持VuGen的选择,那么可以单击右下角的Correlate按钮将这个数据生成关联,也可以单击Create Rule按钮将其转化为一个规则(该功能在第3.7.4节再详细介绍),如图3.144所示。

5092135_17.jpg

图3.144  单击Correlate按钮确认自动关联的对象

单击Correlate按钮后,便生成了一个关联,关联的前后内容和所属Action也被列了出来,自动关联结束,如图3.145所示。

5092135_18.jpg

图3.145  确认后的自动关联对象

切回到Script模式看看脚本发生了什么变化,首先脚本中增加了以下内容:

// [WCSPARAM WCSParam_Diff1 44 98852.6810044552fAitHDtpHHQVzzzHDAfAiptAizHf] Parameter {WCSParam_Diff1} created by Correlation Studio

web_reg_save_param("WCSParam_Diff1",

"LB=userSession value=",

"RB=>",

"Ord=1",

"RelFrameId=1.2.1",

"Search=Body",

"IgnoreRedirections=Yes",

LAST);

这里多了一个关联函数,而关联出来的内容被保存到一个叫做WCSParam_Diff1的参数中去。再看web_submit_data()函数:

web_submit_data("login.pl",

"Action=http://127.0.0.1:1080/WebTours/login.pl",

"Method=POST",

"TargetFrame=body",

"RecContentType=text/html",

"Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",

"Snapshot=t2.inf",

"Mode=HTML",

ITEMDATA,

"Name=userSession", "Value={WCSParam_Diff1}", ENDITEM,

"Name=username", "Value=admin", ENDITEM,

"Name=password", "Value=admin", ENDITEM,

"Name=JSFormSubmit", "Value=off", ENDITEM,

"Name=login.x", "Value=0", ENDITEM,

"Name=login.y", "Value=0", ENDITEM,

LAST);

提交给服务器的userSession值,已经变成了前面关联获取的{WCSParam_Diff1}参数。再次回放脚本,一切正确,进入系统。

自动关联是通过录制和回放时的服务器返回值比较来确定需要关联的内容,然后帮助生成对应的关联函数,常用在非常标准的动态数据处理中,例如sessionid。在大多数情况下脚本无法正常回放都可以通过自动扫描的方法来生成关联,解决动态数据的问题。

当希望将多次回放脚本的结果作为自动关联的比较参考时,可以切换脚本到Tree下的比较模式,如图3.146所示。

然后单击View菜单中Snapshot下的Select Iteration选项,弹出如图3.147所示的窗口。

5092135_19.jpg 

5092135_20.jpg

图3.146  打开view both recording and replay snapshots模式 图3.147  设置选择测试结果的目录

将多次脚本回放的Result日志添加进来(这个需要通过General Options中的设置每次运行Result重命名才能实现),这样做自动扫描关联就不仅比较录制和最后一次回放的服务器返回了。

但是自动关联有很强的局限性,无法实现特殊的动态数据捕获。例如帖子的ID、作者名、某些表格单元值等,这个时候就需要使用手动关联来解决它了。

3.7.3  手动关联

手动关联是关联应用的最有效手段,通过手动关联函数web_reg_save_param()将想要的字符串保存到一个参数中。通过关联可以捕获服务器返回的标题或正文的文本内容,也可以用来捕获服务器返回的超链接,比如需要获得Discuz!NT2.5论坛版面下的置顶和非置顶帖中顶端帖子的ID。

打开论坛版面,可以看到该板块的所有帖子列表。为了获得需要关联的帖子ID,首先需要分析一下置顶帖的左右边界。

1.关联置顶帖ID

打开源代码,可以发现置顶帖的代码如下所示(代码格式考虑美观略微调整):

t_top3.gif

 

附件

闭合帖子列表置顶帖1

决定帖子ID 407的数据是上面代码中带下画线的内容,t_top后的数字并不包含在其中,因为不同的置顶等级决定了该数据的变化。所以可以通过设置左边界为p><p>web_reg_save_param(

"LB=

topicicon

 

闭合帖子列表非置顶帖1

相对置顶帖,这个ID的关联要简单很多,设置左边界为p

web_reg_save_param("topicid",

"LB=

Ø All

指服务器返回的所有内容。

关于Search in这个选项,一般使用得比较多的是Noresource,因为需要关联的内容一般都存放在HTML页面中,并且使用Noresource被关联到的内容又比较少(只返回一个HTML页面)比较适合常用处理,如果某些信息是放在HTTP头内的,那么只能用     Header了。

Save Length

关联出来的内容所需要保存的长度。

例如:通过左右边界关联出来的内容是“sessionid=123456&action=work”,那么如何获得需要的sessionid信息呢?可以使用Save Length来实现,注意这里必须确保被关联内容的长度恒定。将Save Length设置为16,关联出来的结果就变成“sessionid=123456”了,如果想得到后面的sessionid值,就要靠Save Offset选项了。

Save Offset

设置关联的内容偏移量,从第几位开始进行关联操作。继续上面的例子,如果需要获得123456这个字符串,则需要设置Save Offset为10,同时设置Save Length为6即可。

通过Save Length和Save Offset的设置,我们就可以方便地抓取服务器返回内容的任意一个部分了。

关联可以调整偏移量和长度,那么参数能做到吗?当然可以,如果需要对一个参数值进行偏移和长度设置,则需要使用lr_save_var()函数,例如下面的代码:

lr_save_string("I come from shanghai","city");

lr_save_var(lr_eval_string("{city}"),6,0,"result");

//从city这个参数中取6位长度的内容保存到result参数中

lr_save_var(lr_eval_string("{city}")+7,4,0,"result");

//从city这个参数的第7位开始取4个长度的内容保存到result参数中

可以看到运行的结果是:

Action.c(3): Notify: Saving Parameter "city = I come from shanghai"

Action.c(4): Notify: Saving Parameter "result = I come"

Action.c(5): Notify: Saving Parameter "result = from"

问题:

前面关联的左右边界都是静态的。如果左右边界是动态的,并且系统返回的id是不定长度的,那么如何使用关联函数将该id取出呢?这个问题在现实情况中会经常遇到,仅仅通过一个关联函数是无法处理的,这个时候还需要使用一个函数strtok()来进行字符内容切割(类似于正则表达式)。

strtok()函数的作用是通过某个分隔符来切分内容。

例如:

char city[1000];

char * token;

extern char * strtok(char * string, const char * delimiters ); //这个函数是扩展的要声明

strcpy(city,"this is shanghai!");

token = (char *)strtok(city," ");

lr_error_message(token);

token = (char *)strtok(NULL," ");

lr_error_message(token);

token = (char *)strtok(NULL," ");

lr_error_message(token);

通过这个函数可以得到三个字符:this、is、shanghai。通过空格来分隔字符串,可以得到第一个符合该条件的内容,如果需要继续分隔就使用strtok(NULL," ");语句。如果关联出来的内容sessionid是变动长度的,如"sessionid=54321123&action=work",则如何获得这个变动长度的sessionid呢?使用下面的代码即可解决:

char temp[100];

char * token;

extern char * strtok(char * string, const char * delimiters );

lr_save_string("sessionid=54321123&action=work","param");

strcpy(temp,lr_eval_string("{param}"));//取出参数值,并且赋值给变量temp

token = (char *)strtok(temp,"&");//使用&符号作为分隔符

这个时候token="sessionid=54321123",并且是根据&符号分隔的,所以id的长度可以任意变化,而token中的sessionid可以通过关联的时候Save Offset进行处理,或者使用strtok()函数对等号再次进行处理。

3.7.6  关联函数的高级使用

上面详细介绍了关联的作用和关联函数的详细选项,那么在工作中除了要使用关联函数获得服务器返回以外,还能做什么呢?

例如论坛一个版面中有20个帖子,如何实现随机单击其中某一个帖子的操作呢?回想一下关联选项Ord=All的时候关联出来的结果是不是一个参数数组?既然是参数数组,怎么从参数数组中取出一个随机的值呢?

在不同的LoadRunner版本中处理这个问题使用不同解决方法,现在来分别了解一下具体的方案(这里关联后的参数名为link,设置Ord为All)。

LoadRunner 9系列

在LoadRunner 9中做这个操作非常简洁,因为有了参数数组函数,所以只需要这样写就可以了:

char * siteval;

siteval =lr_paramarr_random(link)

即直接从参数数组link中取一个随机的值。

问题:如果需要随机选择前10个帖子怎么办?

Lr_paramarr_random()函数的随机范围其实是根据lr_paramarr_len()决定的。比如数组长度是20,随机值介于1~20之间,现在手动将这个参数数组设置得小一些,问题就解决了:

char * siteval;

lr_save_string("10","link_count");

siteval =lr_paramarr_random(link);

思考:如果需要随机获取关联结果中的第5至第10个对象,该如何处理呢?

在这种情况下,需要引入随机数,生成随机值为5~10的正整数,再调用lr_paramarr_idx()函数进行处理即可。

如果使用的是LoadRunner9以前的版本,没有这个参数数组函数怎么办?

LoadRunner 8以前的版本

假设存在关联后的参数数组为{link},数组记录总个数为20,需要取得其中的一个随机关联值可以这样写:

char linkname[100],num[100];

int randnum;

//关联和请求操作省略

randnum=rand()%atoi(lr_eval_string("{link_count}"))+1;//获得关联参数数目内的随机数字

strcpy(linkname,"{link_");

//lr_error_message("%s",linkname);

itoa(randnum,num,10);

strcat(linkname,num);

strcat(linkname,"}");

//lr_error_message"%s",linkname);

lr_save_string(lr_eval_string(linkname),"temp");

这段代码看起来是比较头疼的,因为涉及了很多新的函数。

atoi()类型强制转换函数的作用是将字符串型的内容转化为整数型。

atoi(字符串);

由于使用求余操作是对一个数字进行操作,所以需要使用atoi将参数转化为正整数。

使用Rand()%atoi(lr_eval_string("{link_count}")可以得到0~19的随机正整数。

strcpy()字符复制函数就是将一个字符串复制到一个变量中去。

strcpy(变量名,需要复制的字符串内容);

所以strcpy(linkname,"{link_"}的作用是将"{link_"这个内容保存到变量linkname中。

itoa()也是一个强制类型转换函数,和atoi()相反,它是将整数型内容转化为字符串型。

itoa(数字型,字符串,转化格式);

这里转化格式使用的是十进制。为了拼接参数数组,需要生成" {link_2}"这样的参数,通过前面的随机函数已经生成1~20的随机正整数,现在需要把这个数字拼接上去,这里使用strcat()来实现,由于 strcat()必须使用字符串,所以需要将随机整数randnum转化成字符串型的num。

strcat()是一个字符添加函数,它将一个字符串附加在一个变量后。

strcat(变量名,字符串);

接着将上面生成的字符串继续拼接到linkname变量中。

这样就拼接出了linkname="{link_2}",在讲述参数化的时候提到过参数和变量的调用,当变量这样写的时候就可以直接读取到参数名的值。所以使用lr_eval_string()可以将这个变量对应的参数值取出,再通过lr_save_string()将值存放到另一个参数temp中去,最后参数temp就存放了{link_2}参数所对应的值了。

如果需要得到1~10的随机记录呢?这个时候只需要在随机数生成的时候做点手脚就行了。

rndnum=rand()%atoi(lr_eval_string("{link_count}"))+1;//获得关联参数数目内的随机数字

把这段代码修改为:

rndnum=rand()%10+1;//得到1~10的随机数字

在这里最好先做一个判断,避免出现帖子少于10个的问题。

如果需要得到5~10的随机记录呢?这个时候还是随机数生成的操作,如何生成一个范围内的随机数呢?通过公式rand()%(max-min+1)+min能生成从最小值到最大值之间的随机数,所以只需要写为以下形式即可:

Rndnum=rand()%(10-5+1)+5;

LoadRunner 8系列

到了 LoadRunner 8.x系列,VuGen提供了一个新的函数来帮助我们快捷地处理类似的类型转化操作。这个函数就是sprintf(),sprintf()和C语言中的 printf()函数十分相似,使用它可以生成带格式的字符串,从而帮助我们快捷地完成一个特殊格式拼接过程。

sprintf(变量名,格式,值)

例如可以这样写:

char temp[100];

sprintf(temp,"welcome %dtesting",51);

lr_error_message(temp);

可以看到结果是"welcome 51testing",通过这个函数将数字51拼接到了这个字符串中。

还是前面的脚本,看看在LoadRunner 8.x中怎么写,现在可以将脚本改为以下形式:

char linkname[100];

int randnum;

randnum=rand()%atoi(lr_eval_string("{link_count}"))+1;//获得关联参数数目内的随机数字

sprintf(linkname,"{link_%d}",rndnum);

lr_save_string(lr_eval_string(linkname),"temp");

这样直接就把随机的rndnum变量放在了linkname变量中,并且生成linkname= "{link_2}"这样的变量。后面的按照LoadRunner 7系列的做法就行了,是不是方便了      很多呢?

通过上面的方法就能处理常见的一些在关联后需要进行随机处理的情况。例如:现在需要这样的脚本,访问论坛首页,登录后检查所有在线用户,然后随机给所有的在线普通会员发一条广告短信息,那么这个脚本怎么去做呢?

分析一下业务:作为一个用户,首先要登录系统,然后查看到所有的在线用户,依次给在线的用户发送短信息。录制一个用户执行以上操作的脚本。如何获得在线的用户信息?在首页的最下面可以看到在线用户的信息,通过HTML代码可以发现普通用户和管理员的区别在于用户名前的图片名。

images%5Cgroupicons%5Cmember.gif

admin00011

普通用户使用的图片是member.gif,而管理员使用的是admin.gif,所以可以通过这个信息来做一个关联操作,得到所有用户信息前是member.gif的用户id。

web_reg_save_param("member",

"LB=member.gif\" />

"RB=.aspx",

"Ord=ALL",

"Search=NoResource",

LAST);

web_url("fristpage","URL=http://192.168.0.200",LAST);

按照代码填写关联的边界,运行后会发现关联失败,原因来自于member.gif" />和

",

"RB=

",

"Ord=1",

"Search=NoResource",

LAST);

web_url("userinfo","URL=http://192.168.0.200/userinfo-{userid}.aspx",LAST);

web_submit_data("usercppostpm.aspx",

"Action=http://192.168.0.200/usercppostpm.aspx?msgtoid={userid}",

"Method=POST",

"TargetFrame=",

"RecContentType=text/html",

"Referer=http://192.168.0.200/usercppostpm.aspx?msgtoid=1038",

"Snapshot=t14.inf",

"Mode=HTML",

ITEMDATA,

"Name=msgto", "Value={username}", ENDITEM,

"Name=subject", "Value=广告测试", ENDITEM,

"Name=message", "Value=广告测试", ENDITEM,

"Name=sendmsg", "Value=立即发送", ENDITEM,

LAST);

}

Return 0;

}

补充:

表3.14  关联中常用的转义内容

转义内容

说明

\b

Backspace键

\f

换页

\n

换行

\r

回车

\t

水平制表符

\v

垂直制表符

\'

单引号标记

\"

双引号标记

\\

反斜杠

\?

文本问号

5092135_28.jpg

关联的使用要点:

1.什么内容需要关联

当脚本中的数据每次回放都发生变化时,并且这个动态数据在后面的请求中需要发送给服务器,那么这个内容就需要通过关联来询问服务器,获得该数据的变化结果。当确认关联的内容后,要确认所需要的数据是在哪个请求中返回的,并且定位该数据的位置和特征,以及左右边界。

2.关联的边界如何设置

左右边界是定位动态数据的关键,但是想要精确定位数据的左右边界并不是一件容易的事,可以通过先松后紧的方式来达到这个目标。首先在做关联的时候设置一个比较明确固定的值,确保能够将所需要的内容整体保存为参数,其次再根据返回的内容进一步细化边界值,一步步达到准确关联结果的目的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值