安装LR脚本编译器VUGen,安装的过程很简单将VUGen的安装包COPY到需要安装的机器上,根据安装想到就可以安装成功,同时安装一个补丁;注意如果使用的机器上已经安装了LR,则不需要这个步骤;
安装LR的一个测试实例网站,这是LR用来做培训的一个网站程序,安装后会提供一个JAVA script写的网站同时提供一个Apache的Web服务器;在安装的过程也很简单只需要根据安装向导安装就可以,安装完成后将APPL-MToursPatch-58目录下的5个class文件覆盖到安装目/MercuryTours/servlets/com/mercurytours/servlet;然后将D:/Program Files/Mercury Interactive/MercuryTours/JavaSoft/JRE/1.2下的bin目录和Lib目录备份更新为新版本的相同信息;将APPL-MToursPatch-58的CascadeMenu.js文件覆盖到安装目录/MercuryTours/public_html/jscript;
简单测试:启动服务,启动浏览器输入:http://localhost/servlets/ com.mercurytours.servlet.WelcomeServlet;如果显示正确的页面说明安装成功;
2) 录制脚本
启动VUGen;
选择“单协议脚本”—“web(HTTP/HTML)”,如下图所示:
点击确定,选择应用程序,输入录制的URL,如下图所示:
点击确定后开始录制脚本;
录制脚本的过程中需要注意录制脚本的规范化,比如:在开始一个事务的时候直接插入事务,对于不同的交易定义不同的Action,脚本录制完成如下图所示:
上图中红框标识出来的就是需要注意规范的地方,在这次培训中收益不小;
完成这个步骤我们的脚本就录制完成了。
3) 脚本修改及优化;
录制完成脚本后我们先运行一下,这个脚本可以运行,但是在运行到删除机票的时候出错,这是因为我们录制的脚本在没有做任何修改的时候是应用是很不灵活的,这个错误是因为我们选择删除的机票已经删除,所以再次运行的时候会找不到表单,所以我们需要对脚本进行修改成为可用的测试脚本,那么下面我们就对脚本进行修改和优化;
参数化:脚本中的参数化就是将其中固定的值(或者录制的值)通过参数修改为可变的值,这个过程就是参数化;更详细的参数化,请参与LR的用户手册;
在这个脚本中我们可以对登录的用户名和密码进行参数化,脚本如下所示:
lr_start_transaction("login");
web_submit_form("com.mercurytours.servlet.SignonServlet",
"Snapshot=t2.inf",
ITEMDATA,
"Name=userName", "Value=test1", ENDITEM,
"Name=password", "Value=111111", ENDITEM,
"Name=login.x", "Value=23", ENDITEM,
"Name=login.y", "Value=6", ENDITEM,
LAST);
lr_end_transaction("login",LR_AUTO);
在上述的一段脚本中标红的部分是需要参数化的部分,选择红色部分,点击右键,选择“替换为新参数”,如下图所示:
在弹出的对话框中,输入参数名:name,如下图所示:
下面我们重点介绍一下参数的类型。
n DateTime:很简单,在需要输入日期/时间的地方,可以用DateTime 类型来替代。
其属性设置也很简单,选择一种格式即可。当然也可以定制格式。
n Group Name:暂时不知道何处能用到,但设置比较简单。在实际运行中,LoadRunner
使用该虚拟用户所在的Vuser Group 来代替。但是在VuGen 中运行时,Group Name
将会是None
n Load Generator Name:在实际运行中,LoadRunner 使用该虚拟用户所在Load
Generator 的机器名来代替。
n Iteration Number:在实际运行中,LoadRunner 使用该测试脚本当前循环的次数来
代替。
n Random Number:随机数。很简单。在属性设置中可以设置产生随机数的范围
n Unique Number:唯一的数。在属性设置中可以设置第一个数以及递增的数的大小。
注意:使用该参数类型必须注意可以接受的最大数。例如:某个文本框能接受的
最大数为99。当使用该参数类型时,设置第一个数为1,递增的数为1,但100 个
虚拟用户同时运行时,第100 个虚拟用户输入的将是100,这样脚本运行将会出错。
注意:这里说的递增意思是各个用户取第一个值的递增数,每个用户相邻的两次循
环之间的差值为1。举例说明:假如起始数为1,递增为5,那么第一个用户第一
次循环取值1,第二次循环取值2;第二个用户第一次循环取值为6,第二次为7;
依次类推。
n Vuser ID:设置比较简单。在实际运行中,LoadRunner 使用该虚拟用户的ID 来代
替,该ID 是由Controller 来控制的。但是在VuGen 中运行时,Vuser ID 将会是 –1。
n File:需要在属性设置中编辑文件,添加内容,也可以从现成的数据库中取数据(下
面我们将会介绍)
n User Defined Function:从用户开发的dll 文件提取数据。就目前我认为,这种方式
没有必要。VuGen 支持C 语言的语法,在VuGen 中重新编写类似的函数应该不难。
(以上内容来源于:LR使用手册.pdf)
点击确定,这样就设置了一个参数,同样的我们对密码进行参数化;完成后脚本如下所示:
lr_start_transaction("login");
web_submit_form("com.mercurytours.servlet.SignonServlet",
"Snapshot=t2.inf",
ITEMDATA,
"Name=userName", "Value={name}", ENDITEM,
"Name=password", "Value={password}", ENDITEM,
"Name=login.x", "Value=23", ENDITEM,
"Name=login.y", "Value=6", ENDITEM,
LAST);
lr_end_transaction("login",LR_AUTO);
由上述的脚本可以看出用户名和密码由两个用{}括起来的参数代替,上述脚本中标红的就是参数化的参数。
这样只是初步的参数化,然后我们选择“Vuser”—“参数列表”,如下图所示:
选择name,“添加列”,然后选择“按名称”选择name,选择password,选择“按名称”选择password,如下图所示:
通过Web网站注册新的用户,test2、test3……,用户注册如下图所示:
然后修改参数,使用记事本修改,如下图所示:
这样保存后参数化就完成了。然后我们看一下参数选择的策略;
选择下一行的策略有四种Sequential(顺序选择)、Random(随机选择)Unique(选择唯一值),Same line as name(这个是在有两行关联的数据时,可以有一个参数选择这种方式),重点说一下前面三个选择方式:
n Sequential:按照顺序一行行的读取。每一个虚拟用户都会按照相同的顺序读取
n Random:在每次循环里随机的读取一个,但是在循环中一直保持不变
n Unique :唯一的数。注意:使用该类型必须注意数据表有足够多的数。比如
Controller 中设定20 个虚拟用户进行5 次循环,那么编号为1 的虚拟用户取前5
个数,编号为2 的虚拟用户取6-10 的数,依次类推,这样数据表中至少要有100
个数据,否则Controller 运行过程中会返回一个错误。
n Same Line As 某个参数(比如Name):和前面定义的参数Name 取同行的记录。
通常用在有关联性的数据上面。
更新值的时间:
n Each Occurrence:在运行时,每遇到一次该参数,便会取一个新的值
n Each iteration:运行时,在每一次循环中都取相同的值
n Once:运行时,在每次循环中,该参数只取一次值
(以上内容来源于:LR用户使用手册.pdf)
完成上面的步骤我们对于用户和密码的参数化就完成了,运行一下脚本,这里注意一个小技巧:就是打开“运行设置”-“日志”,选择扩展日志,然后选中“参数替换”,如下图所示:
通过上图设置,在运行脚本的时候,可以在脚本运行日志中看到参数替换的情况,运行日志如下所示:
vuser_init.c(22): 通知: Transaction "首页" ended with "Pass" status (Duration: 7.8871).
vuser_init.c(26): 通知: Transaction "login" started.
vuser_init.c(28): 通知: 参数替换:参数“name”=“test 1 ”
vuser_init.c(28): 通知: 参数替换:参数“password”=“ 111111”
上述日志说明我们的参数化成功了。
那我们看看这个脚本是不是其他地方方还可以参数化,是的,比如我们预订机票的城市,信用卡的卡号等等;只要是可以变化的基本上都可以参数化;
关联
关联是脚本修改过程中重要的步骤,我们先看下面一段脚本代码:
lr_start_transaction("bookflight");
lr_think_time(103);
web_submit_data("com.mercurytours.servlet.ReservationServlet",
"Action=http://localhost/servlets/com.mercurytours.servlet.ReservationServlet?procSub=1&pg=1",
"Method=POST",
"RecContentType=text/html",
"Referer=http://localhost/servlets/com.mercurytours.servlet.ReservationServlet",
"Snapshot=t3.inf",
"Mode=HTML",
ITEMDATA,
"Name=tripType", "Value=roundtrip", ENDITEM,
"Name=passCount", "Value=1", ENDITEM,
"Name=fromPort", "Value= Acapulco ", ENDITEM,
"Name=fromMonth", "Value=06", ENDITEM,
"Name=fromDay", "Value=13", ENDITEM,
"Name=toPort", "Value= Zurich ", ENDITEM,
"Name=toMonth", "Value=06", ENDITEM,
"Name=toDay", "Value=14", ENDITEM,
"Name=servClass", "Value=First", ENDITEM,
"Name=airline", "Value=No Preference", ENDITEM,
"Name=findFlights.x", "Value=29", ENDITEM,
"Name=findFlights.y", "Value=7", ENDITEM,
LAST);
web_submit_form("com.mercurytours.servlet.PurchaseServlet",
"Snapshot=t4.inf",
ITEMDATA,
"Name=outFlight", "Value=Blue Skies Airlines$190$706$5:03$", ENDITEM,
"Name=inFlight", "Value=Blue Skies Airlines$910$706$12:23$", ENDITEM,
"Name=reserveFlights.x", "Value=46", ENDITEM,
"Name=reserveFlights.y", "Value=12", ENDITEM,
LAST);
lr_think_time(31);
web_submit_form("com.mercurytours.servlet.PurchaseServlet_2",
"Snapshot=t5.inf",
ITEMDATA,
"Name=passFirst0", "Value=li", ENDITEM,
"Name=passLast0", "Value=gang", ENDITEM,
"Name=pass.1.meal", "Value=No preference", ENDITEM,
"Name=creditCard", "Value=American Express", ENDITEM,
"Name=creditnumber", "Value=111111111", ENDITEM,
"Name=cc_exp_dt_mn", "Value=None", ENDITEM,
"Name=cc_exp_dt_yr", "Value=None", ENDITEM,
"Name=cc_frst_name", "Value=", ENDITEM,
"Name=cc_mid_name", "Value=", ENDITEM,
"Name=cc_last_name", "Value=", ENDITEM,
"Name=billAddress1", "Value= 1325 Borregas Ave. ", ENDITEM,
"Name=billAddress2", "Value=", ENDITEM,
"Name=billCity", "Value= Sunnyvale ", ENDITEM,
"Name=billState", "Value=CA", ENDITEM,
"Name=billZip", "Value=94089", ENDITEM,
"Name=billCountry", "Value=UNITED STATES", ENDITEM,
"Name=delAddress1", "Value= 1325 Borregas Ave. ", ENDITEM,
"Name=delAddress2", "Value=", ENDITEM,
"Name=delCity", "Value= Sunnyvale ", ENDITEM,
"Name=delState", "Value=CA", ENDITEM,
"Name=delZip", "Value=94089", ENDITEM,
"Name=delCountry", "Value=UNITED STATES", ENDITEM,
"Name=buyFlights.x", "Value=84", ENDITEM,
"Name=buyFlights.y", "Value=7", ENDITEM,
LAST);
lr_end_transaction("bookflight",LR_AUTO);
以上这段代码是定制机票时的信息,我们注意一下上面标红的地方,做一个这样的操作,在脚本中,将标红的城市修改为:London和New York,然后运行一下脚本,看看会出现什么情况:
ookflight.c(30): 错误 -27979: 找不到请求的表单 [MsgId: MERR-27979]
bookflight.c(30): web_submit_form("com.mercurytours.servlet.PurchaseServlet") 最高严重级别为“ERROR”,0 个正文字节,0 个标头字节 [MsgId: MMSG-26388]
bookflight.c(30): 通知: Transaction "bookflight" ended with "Fail" status (Duration: 0.5445).
脚本运行后有如上错误,为什么会这样呢,大家看脚本中的
"Name=outFlight", "Value=Blue Skies Airlines$190$706$5:03$", ENDITEM,
"Name=inFlight", "Value=Blue Skies Airlines$910$706$12:23$", ENDITEM,
这两句话,其实被测系统为每个定制的航班生成了一个序列号,就是标红的部分,但是我们修改两个城市后,系列号就不对应了,所以出现上述错误,那么我们如何解决这个问题呢,这就需要用到关联,那么什么是关联呢,所谓的关联就是通过查找上下问中的信息,取出变化的信息来替代脚本中的信息,比如系列号,随机数等一般需要关联。
我们来分析一下上面的例子,在这个定制机票的例子中,填写好信息后提交的过程中生成了这个序列号,我们只需要在生成序列号的页面中找到这个序列号并且保存到一个变量中,然后替换Value的值就可以了;
这个过程如何实现呢,我们将脚本先切换到树形结构,然后选择web_submit_data("com.mercurytours.servlet.ReservationServlet",点击右键“在之前插入”在查找函数中输入:web_reg_sava_param然后点击确定,如下图所示:
在上图中输入参数名、左边界、右边界;参数名我们定义为inflight;左边界,我们需要打开网站,找到录制的页面查找:如下图所示:
我们可以看到左边界我们可以定义为<input type=radio checked name=inFlight value=/",有边界可以定义为:/">,在这里需要注意一个小细节,就是通过“/”的C语言转义字符将“"”进行转义,因为在LR中认为"是一个标识符;
点击确定,完成操作,通过同样的方式将Outflight的参数,查看脚本,我们得到如下函数:
web_reg_save_param("inflight",
"LB=<input type=radio checked name=inFlight value=/"",
"RB=/">",
LAST);
web_reg_save_param("outflight",
"LB=<input type=radio checked name=inFlight value=/"",
"RB=/">",
LAST);
运行一下脚本:
bookflight.c(16): 通知: 正在保存参数“inflight = Blue Skies Airlines$300$358$12:23$”
bookflight.c(16): 通知: 正在保存参数“outflight = Blue Skies Airlines$300$358$12:23$”
将这个参数的值替换到脚本中如下:
web_submit_form("com.mercurytours.servlet.PurchaseServlet",
"Snapshot=t4.inf",
ITEMDATA,
"Name=outFlight", "Value={outflight}", ENDITEM,
"Name=inFlight", "Value={inflight}", ENDITEM,
"Name=reserveFlights.x", "Value=46", ENDITEM,
"Name=reserveFlights.y", "Value=12", ENDITEM,
LAST);
在运行一次脚本:
bookflight.c(16): 通知: 正在保存参数“outflight = Blue Skies Airlines$30$358$5:03$”
bookflight.c(16): 通知: 正在保存参数“inflight = Blue Skies Airlines$300$358$12:23$”
bookflight.c(16): 资源“http://localhost/images/forms/continue.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
bookflight.c(16): 资源“http://localhost/images/caribbean_menu.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
bookflight.c(16): 资源“http://localhost/images/member_menu.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
bookflight.c(16): 资源“http://localhost/images/guest_menu.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
bookflight.c(16): 资源“http://localhost/images/alaska_menu.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
bookflight.c(16): web_submit_data("com.mercurytours.servlet.ReservationServlet") 已成功,21653 个正文字节,533 个标头字节,47 个成块开销字节 [MsgId: MMSG-26385]
bookflight.c(39): 通知: 参数替换:参数“outflight”=“Blue Skies Airlines$30$358$5:03$”
bookflight.c(39): 通知: 参数替换:参数“inflight”=“Blue Skies Airlines$300$358$12:23$”
bookflight.c(39): 将表单提交到“http://localhost/servlets/com.mercurytours.servlet.PurchaseServlet”,目标帧=“” [MsgId: MMSG-27978]
bookflight.c(39): 资源“http://localhost/jscript/CascadeMenu.js”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
从上述的日志可以看到运行成功了,这就是一个比较简单的关联。
我们在看另外一个问题,在删除航班过程中,由于录制的过程中航班已经被删除,所以下次回放脚本是就会出现表单找不到的错误,那么这个问题我们如何来解决呢,我们来看一下系统运行的机制,我们可以看到,删除航班的过程就是选择一个航班然后点击删除就可以了,那么我们只要找到所有的航班然后从中随机选择一个删除就可以了,我们来看一下我们的脚本:
lr_start_transaction("delflight");
lr_think_time(46);
web_submit_data("com.mercurytours.servlet.IteneraryServlet_2",
"Action=http://localhost/servlets/com.mercurytours.servlet.IteneraryServlet?procSub=1",
"Method=POST",
"RecContentType=text/html",
"Referer=http://localhost/servlets/com.mercurytours.servlet.IteneraryServlet",
"Snapshot=t7.inf",
"Mode=HTML",
ITEMDATA,
"Name=flight_83", "Value=on", ENDITEM,
"Name=removeSelected.x", "Value=141", ENDITEM,
"Name=removeSelected.y", "Value=5", ENDITEM,
LAST);
lr_end_transaction("delflight",LR_AUTO);
脚本中标红的部分来负责删除航班,我们只需要将其中flight_83;进行关联就可以了首先我们通过函数web_reg_save_param函数在这个页面中找出所有的航班;
web_reg_save_param("FLIGHT",
"LB=<input type=/"checkbox/" name=/"",
"RB=/"",
"ORD=All",
LAST);
运行一下脚本:
delflight.c(14): 通知: 正在保存参数“FLIGHT_1 = flight_ 84 ”
delflight.c(14): 资源“http://localhost/images/nav/html.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 资源“http://localhost/images/nav/boxad1.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 资源“http://localhost/images/banner2.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 资源“http://localhost/images/masts/mast_itinerary.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 资源“http://localhost/images/spacer.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 资源“http://localhost/images/forms/details.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 通知: 正在保存参数“FLIGHT_2 = flight_ 85 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_3 = flight_ 86 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_4 = flight_ 87 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_5 = flight_ 88 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_6 = flight_ 89 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_7 = flight_ 90 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_8 = flight_ 91 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_9 = flight_ 93 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_10 = flight_ 95 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_11 = flight_ 96 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_12 = flight_ 98 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_13 = flight_ 107 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_14 = flight_ 108 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_15 = flight_ 113 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_16 = flight_ 101 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_17 = flight_ 102 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_18 = flight_ 103 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_19 = flight_ 105 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_20 = flight_ 109 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_21 = flight_ 110 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_22 = flight_ 111 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_23 = flight_ 112 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_24 = flight_ 114 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_25 = flight_ 115 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_26 = flight_ 116 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_27 = flight_ 117 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_28 = flight_ 118 ”
delflight.c(14): 通知: 正在保存参数“FLIGHT_29 = flight_ 119 ”
delflight.c(14): 资源“http://localhost/images/forms/cancel_checked.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 资源“http://localhost/images/forms/cancelall.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 资源“http://localhost/images/caribbean_menu.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 资源“http://localhost/images/member_menu.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 资源“http://localhost/images/guest_menu.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 资源“http://localhost/images/alaska_menu.gif”已在缓存中,不会再次下载 [MsgId: MMSG-26655]
delflight.c(14): 通知: 正在保存参数“FLIGHT_count = 29 ”
我们从上述的日志中可以看到,找出了所有的航班,并且“FLIGHT_count = 29 ” ;
然后我们增加一下代码,从上述的29个航班中随机的选择一个:
int flight_count,rnd_number;//loadrunner内部变量需要变成C语言变量
char flight_to_cancel[128];
lr_start_transaction("delflight");
flight_count=atoi(lr_eval_string("{FLIGHT_count}"));//将Loadrunner内部变量转换为C语言变量,保存到变量:flight_count中;
lr_output_message("flight_count:%d /n",flight_count);//将flight_count的值打印出来
do{ srand(time(NULL));
rnd_number = rand() % (flight_count+1);
}while(rnd_number==0);//随机选择一个值给rnd_number;
lr_output_message("rnd_number:%d /n",rnd_number);//输出rnd_number;
sprintf(flight_to_cancel,"{FLIGHT_%d}",rnd_number);//将字符串FLIGHT_83赋予变量flight_to_cancel;
lr_save_string (lr_eval_string (flight_to_cancel),"FLIGHT_TO_CANCEL");//将C语言变量转换为LR内部变量
lr_think_time(46);
web_submit_data("com.mercurytours.servlet.IteneraryServlet_2",
"Action=http://localhost/servlets/com.mercurytours.servlet.IteneraryServlet?procSub=1",
"Method=POST",
"RecContentType=text/html",
"Referer=http://localhost/servlets/com.mercurytours.servlet.IteneraryServlet",
"Snapshot=t7.inf",
"Mode=HTML",
ITEMDATA,
"Name={FLIGHT_TO_CANCEL}", "Value=on", ENDITEM, //关联Name
"Name=removeSelected.x", "Value=141", ENDITEM,
"Name=removeSelected.y", "Value=5", ENDITEM,
LAST);
lr_end_transaction("delflight",LR_AUTO);
我们在思考另外一个问题,我们将选择航班的城市参数化,同时我们又不希望出现两个相同的城市,我们如何来实现呢?
先对FromPort和toPort的值进行参数化:
然后通过以下的语句来实现随机选择城市,并且去除相同的城市;
char fromPort[128];
char toPort[128];
strcpy(fromPort,lr_eval_string ("{fromPort}"));
strcpy(toPort,lr_eval_string ("{toPort}"));
while(strcmp(fromPort,toPort)==0){
strcpy(toPort,lr_eval_string ("{toPort}"));
}
另外在培训过程中还讲到了,如何利用web_reg_find函数来判断页面访问是否成功,函数如下:
web_reg_find("Text=Your /n"
" itinerary has been booked!",
"Search=body",
LAST);
这个函数可以判断如果航班定制失败,他将报错。测试一下,我们修改一下信用卡号为字符,在运行一次脚本:
bookflight.c(61): 错误 -26366: 找不到 web_reg_find 的“Text=Your
itinerary has been booked!” [MsgId: MERR-26366]
总结:在这次培训过程中通过对于HTTP协议的脚本的录制和优化以及修改等学习了,参数化、关联、以及页面访问成功与否的判断,同时对于脚本的规范化等方面也有不少的收获。