LR动态脚本的处理
在处理SSO修改密码脚本时遇到一个问题,根据用户名的不同,提交请求中数据会不一样。处理此问题,如果经分析用同类型的账号(每个账号含有的子账号类型和数目一致)测试与实际不同类型账号性能没有大的差别,则用同类型的账号测试只需要简单的修改下脚本即可(实际上也按这种方式处理这个问题了)。但如果不能用同类型的账号测试,则每个用户修改密码提交的请求就不一样,相当于提交的数据是动态的,要构造一个动态的脚本。
最开始想到构造动态脚本的方法是这样的:通过关联得到每种类型子账号的个数,然后定义一个变量,如果一种子账号个数大于0,则用循环拼接成脚本中的一组ITEMDATA信息存在变量中,最后把这个变量放到web_submit_data脚本中相应的位置。但不管怎么构造这个变量,回放时始终报下面的错误信息:
Action.c(395): Continuing after Error -27225: The ""Name=ebsaccounthrms", "Value=hrms**C60004370**BD5F2D8F93A7D53EE040580ACE3256EF**N",ENDITEM," argument (number 18) is not recognized within "ITEMDATA" [MsgId: MERR-27225]
然后在网上搜索,也没找到在web_summit_data请求解决这个错误的方法。貌似web_summit_data中可以用参数或变量替换某一个值,但不能将一组itemdata数据用参数或变量替换。而要解决这个问题,需要用web_custom_request请求。web_custom_request中可以用一个变量来代替整个提交的请求体Body内容,将web_summit_data请求换为web_custom_request请求后,然后回放脚本,通过加检查点、手工验证密码的方式都验证脚本回放成功,业务处理成功。
将web_summit_data请求换为web_custom_request请求时遇到一个小插曲,按网上的方法,“"Name=isFingers", "Value=0", ENDITEM, "Name=c_it_id", "Value=13", ENDITEM,”转换为Body请求体应该是“Body=Name=isFingers&Value=0&Name=c_it_id&Value=13”,但实际上用“Body=isFingers=0&c_it_id=13”即可。在这个问题上也花费了一段时间,最后我把脚本录制为web_custom_request请求的方式才发现自己转换错了。
在录制选项中按以下设置可以将提交数据录制为web_custom_request请求:
1 Action()
2 {
3 //定义变量
4 char str_tmp1[1000];
5 int i;
6
7
8 //此处把每个uid下可能出现的账号和密码都用关联取出来,加了参数“Notfound=warning”,这样关联结果为空也不会报错
9
10 web_reg_save_param("ICARE_UID",
11 "LB/ALNUMIC=EBS_INST\":\"ICARE\",\"IS_FORCE\":\"Y\",\"IS_SELECTED\":\"Y\",\"USER_GUID\":\"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\",\"USER_NAME\":\"",
12 "RB=\"}",
13 "Ord=all",
14 "Notfound=warning",
15 LAST);
16
17 web_reg_save_param("ICARE_Password",
18 "LB/ALNUMIC=EBS_INST\":\"ICARE\",\"IS_FORCE\":\"Y\",\"IS_SELECTED\":\"Y\",\"USER_GUID\":\"",
19 "RB=\",",
20 "Ord=1",
21 "Notfound=warning",
22 LAST);
23
24 web_reg_save_param("HRMS_UID",
25 "LB/ALNUMIC=EBS_INST\":\"HRMS\",\"IS_FORCE\":\"Y\",\"IS_SELECTED\":\"Y\",\"USER_GUID\":\"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\",\"USER_NAME\":\"",
26 "RB=\"}",
27 "Ord=all",
28 "Notfound=warning",
29 LAST);
30
31 web_reg_save_param("HRMS_Password",
32 "LB/ALNUMIC=EBS_INST\":\"HRMS\",\"IS_FORCE\":\"Y\",\"IS_SELECTED\":\"Y\",\"USER_GUID\":\"",
33 "RB=\",",
34 "Ord=1",
35 "Notfound=warning",
36 LAST);
37
38 web_reg_save_param("GERP_UID",
39 "LB/ALNUMIC=EBS_INST\":\"GERP\",\"IS_FORCE\":\"Y\",\"IS_SELECTED\":\"Y\",\"USER_GUID\":\"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\",\"USER_NAME\":\"",
40 "RB=\"}",
41 "Ord=all",
42 "Notfound=warning",
43 LAST);
44
45 web_reg_save_param("GERP_Password",
46 "LB/ALNUMIC=EBS_INST\":\"GERP\",\"IS_FORCE\":\"Y\",\"IS_SELECTED\":\"Y\",\"USER_GUID\":\"",
47 "RB=\",",
48 "Ord=1",
49 "Notfound=warning",
50 LAST);
51
52 web_reg_save_param("GXERP_UID",
53 "LB/ALNUMIC=EBS_INST\":\"GXERP\",\"IS_FORCE\":\"Y\",\"IS_SELECTED\":\"Y\",\"USER_GUID\":\"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\",\"USER_NAME\":\"",
54 "RB=\"}",
55 "Ord=all",
56 "Notfound=warning",
57 LAST);
58
59 web_reg_save_param("GXERP_Password",
60 "LB/ALNUMIC=EBS_INST\":\"GXERP\",\"IS_FORCE\":\"Y\",\"IS_SELECTED\":\"Y\",\"USER_GUID\":\"",
61 "RB=\",",
62 "Ord=1",
63 "Notfound=warning",
64 LAST);
65
66
67
68 web_url("GetEbsAccountListServlet_2",
69 "URL=http://server.huawei.com/account/GetEbsAccountListServlet?uid={ParamUid}&_=1371806275833",
70 "Resource=0",
71 "RecContentType=text/html",
72 "Referer=http://server.huawei.com/account/modifypwd.do?c_it_id=13",
73 "Snapshot=t32.inf",
74 "Mode=HTTP",
75 LAST);
76
77
78
79 /*提交*/
80
81 web_revert_auto_header("x-requested-with");
82
83 web_add_auto_header("Accept",
84 "image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
85
86 web_add_header("Cache-Control",
87 "no-cache");
88
89 lr_think_time(9);
90
91 //录制的原始web_submit_data请求
92
93 // web_submit_data("editpwd.do",
94 // "Action=http://server.huawei.com/account/editpwd.do",
95 // "Method=POST",
96 // "RecContentType=text/html",
97 // "Referer=http://server.huawei.com/account/modifypwd.do?c_it_id=13",
98 // "Snapshot=t36.inf",
99 // "Mode=HTTP",
100 // ITEMDATA,
101 // "Name=isFingers", "Value=0", ENDITEM,
102 // "Name=c_it_id", "Value=13", ENDITEM,
103 // "Name=account", "Value=test704", ENDITEM,
104 // "Name=ebsaccounthrms", "Value=hrms**C60004370**BD5F2D8F93A7D53EE040580ACE3256EF**Y", ENDITEM,
105 // "Name=newPassword", "Value={NewPwd1}", ENDITEM,
106 // "Name=newPasswordAgain", "Value={NewPwd1}", ENDITEM,
107 // "Name=oldPassword", "Value={OldPwd}", ENDITEM,
108 // "Name=pwdshow", "Value=", ENDITEM,
109 // LAST);
110
111
112 //下面拼接BODY内容,放到变量str_tmp1变量中,用于web_custom_request请求提交密码修改
113
114 strcat(str_tmp1,"Body=isFingers=0&c_it_id=13&account=");
115 strcat(str_tmp1,lr_eval_string("{ParamUid}"));
116
117
118 if(lr_paramarr_len("ICARE_UID")>0)
119 for (i=1;i<=lr_paramarr_len("ICARE_UID");i++) {
120 strcat(str_tmp1,"&ebsaccounticare=icare**");
121 strcat(str_tmp1,lr_paramarr_idx("ICARE_UID",i));
122 strcat(str_tmp1,"**");
123 strcat(str_tmp1,lr_eval_string("{ICARE_Password}"));
124 strcat(str_tmp1,"**Y");
125
126 }
127
128 if(lr_paramarr_len("GERP_UID")>0)
129 for (i=1;i<=lr_paramarr_len("GERP_UID");i++) {
130 strcat(str_tmp1,"&ebsaccountgerp=gerp**");
131 strcat(str_tmp1,lr_paramarr_idx("GERP_UID",i));
132 strcat(str_tmp1,"**");
133 strcat(str_tmp1,lr_eval_string("{GERP_Password}"));
134 strcat(str_tmp1,"**Y");
135
136 }
137
138
139 if(lr_paramarr_len("HRMS_UID")>0)
140 for (i=1;i<=lr_paramarr_len("HRMS_UID");i++) {
141 strcat(str_tmp1,"&ebsaccounthrms=hrms**");
142 strcat(str_tmp1,lr_paramarr_idx("HRMS_UID",i));
143 strcat(str_tmp1,"**");
144 strcat(str_tmp1,lr_eval_string("{HRMS_Password}"));
145 strcat(str_tmp1,"**Y");
146
147 }
148
149 if(lr_paramarr_len("GXERP_UID")>0)
150 for (i=1;i<=lr_paramarr_len("GXERP_UID");i++) {
151 strcat(str_tmp1,"&ebsaccountgxerp=gxerp**");
152 strcat(str_tmp1,lr_paramarr_idx("GXERP_UID",i));
153 strcat(str_tmp1,"**");
154 strcat(str_tmp1,lr_eval_string("{GXERP_Password}"));
155 strcat(str_tmp1,"**Y");
156
157 }
158
159 strcat(str_tmp1,"&newPassword=");
160 strcat(str_tmp1,lr_eval_string("{NewPwd1}"));
161 strcat(str_tmp1,"&newPasswordAgain=");
162 strcat(str_tmp1,lr_eval_string("{NewPwd1}"));
163 strcat(str_tmp1,"&oldPassword=");
164 strcat(str_tmp1,lr_eval_string("{OldPwd}"));
165 strcat(str_tmp1,"&pwdshow=");
166
167 lr_output_message("BODY内容是:%s",str_tmp1);
168
169 web_reg_find("Text=The password has been changed successfully!",LAST);
170
171
172 //将web_submit_data请求转换为web_custom_request请求
173
174 web_custom_request("editpwd.do",
175 "URL=http://server.huawei.com/account/editpwd.do",
176 "Method=POST",
177 "RecContentType=text/html",
178 "Referer=http://server.huawei.com/account/modifypwd.do?c_it_id=13",
179 "Snapshot=t14.inf",
180 "Mode=HTML",
181 //"Body=isFingers=0&c_it_id=13&account={ParamUid}&ebsaccounthrms=hrms**C60004370**BD5F2D8F93A7D53EE040580ACE3256EF**Y&newPassword={NewPwd1}&newPasswordAgain={NewPwd1}&oldPassword={OldPwd}&pwdshow=",
182 str_tmp1,
183 LAST);
184
185
186
187 web_url("only4ssoTimeUpdate.do_2",
188 "URL=http://server.huawei.com/account/only4ssoTimeUpdate.do",
189 "Resource=0",
190 "RecContentType=text/plain",
191 "Referer=http://server.huawei.com/account/editpwd.do",
192 "Mode=HTTP",
193 LAST);
194
195 return 0;
196 }
[华为专家回复]:
1、不能用WEB_SUBMIT_DATA的根本原因是,在该函数中,逗号视为一个参数的分隔符,你的表达方式被解析后,系统认为那包含了三组值的字符串是函数的一个参数,从而视为参数错误。
2、在LR的函数中,如果在函数调用中使用参数或变量的话,脚本解析时优先满足函数调用的形式规则,如上文中不管是用web_submit_date还是web_custom_request都不可能用一个变量来代替多个参数。例如:函数A(a1,a2,a3....)形式调用 时,函数优先匹配形参,如果用变量Y代替形参a2时,函数解析认为Y代替一个形参a2,然后函数会在提取形参a2的实际值时,去读取变量Y的值来代替。
在上文的第一种场景中,笔者希望以参数Y代表A1,a2,a3,结果就是函数首先将包含了A1,a2,a3的变量Y视为函数的一个形参,进而获得Y值,并将此值赋给该一个参数(实际上函数需要的是三个参数),则函数在解析实际参数内容时,就无法识别Y串的有效性了。
第二种场景,换了web_custom_request之所以可行,并非该函数支持变量替换多个形参,而是因为通过BODY体的调用方法,将第一种场景中必须使用多个形参赋的值在一个参数中实现了,在实现上,也能发现是使用变量STR_TMP!来代替了函数的一个形参,从而执行成功。
因此,大家在使用LR的函数中插入变量或参数的话,需要注意满足函数对参数形式的要求,以下举例说明一下:
web_submit_data("newsPaperPage.do",
"Action=http://app.huawei.com/paper/newspaper/newsPaperPage.do?method=refreshNewsInfoPage",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html",
"Referer=http://app.huawei.com/paper/newspaper/newsPaperPage.do?method=showLatestNewsInfoList&sortId=2&cateId=5561#newsInfo=11381,1",
"{sss},
//上一行为错误的使用方法,即使参数SSS中有反引号也不行,因为函数在获取SSS值之前优先进行了参数合法化检查,发现没有反引号
"{iiii}",
//上一行为正确的使用方法,函数会在解析该形参的实际值时去读取参数iiii的值 ,作为参数的使用值,这里有点绕口,一个是指函数的调用参数,一个是指LR中的参数。
ITEMDATA,
"Name=infoId", "Value=11381", ENDITEM,
str_tmp1,
//上一行为正确的使用方法,函数会在解析该形参的实际值时,读取变量str_tmp1的值。注意在LR中变量与参数是两类不同的处理,如果此处是参数,就需要使用上一处的形式
"Name=c{yyy}", "Value=1", ENDITEM,
//上一行为正确的使用方法,函数会在解析Name字段的值时,读取参数YYY的值,并与前置的C合并,作为NAME的取值
EXTRARES,
"Url=../css/othercss/img/c_boxTop.gif",
"Referer=http://app.huawei.com/paper/newspaper/newsPaperPage.do?method=showLatestNewsInfoList&sortId=2&cateId=5561", ENDITEM,
LAST);
LR动态脚本的处理的更多相关文章
- 【开源】.Net 动态脚本引擎NScript
开源地址: https://git.oschina.net/chejiangyi/NScript 开源QQ群: .net 开源基础服务 238543768 .Net 动态脚本引擎 NScript ...
- JavaScript 动态脚本
动态脚本,指的是在页面加载时不存在,但将来的某一个时刻通过修改DOM动态添加的脚本. <script type="text/javascript"> function ...
- DOM动态脚本和动态样式
动态脚本 [定义] 在页面加载时不存在,但将来的某一时刻通过修改DOM动态添加的脚本. [方式] [1]插入外部文件方式 var script = document.createElement(&qu ...
- js插入动态脚本
原文章:https://www.w3cmm.com/dom/insert-javascript.html 动态脚本指的是在页面加载时不存在,但将来的某一时刻通过修改该DOM动态添加的脚本.和操作HTM ...
- LR性能测试脚本增强与调试
脚本增强与调试 一般来说,使用LR的Vugen录制的脚本并不能直接用于测试,需要对脚本进行各方面的增强,主要包括添加注释.关联.检查点.事务.参数化.日志输出等.下面结合刚完成的一个web项目性能测试 ...
- 【前端基础】动态脚本与JSONP
博主入职两个月了,越来越感受到打好基础对于前端工程师的重要性,在向着狂拽酷炫的框架&构建工具高速狂奔之前,必须有一个坚实的基础打底,才不至于轻易翻车.所以博主最近一直在恶补<JS高级程序 ...
- 使用Roslyn脚本化C#代码,C#动态脚本实现方案
[前言] Roslyn 是微软公司开源的 .NET 编译器. 编译器支持 C# 和 Visual Basic 代码编译,并提供丰富的代码分析 API. Roslyn不仅仅可以直接编译输出,难能可贵的就 ...
- doubleclick cookie、动态脚本、用户画像、用户行为分析和海量数据存取 推荐词 京东 电商 信息上传 黑洞 https://blackhole.m.jd.com/getinfo
doubleclick cookie https://mp.weixin.qq.com/s/vZUj-Z9FGSSWXOodGqbYkA 揭密Google的网络广告技术:基于互联网大数据视角 原创: ...
- Javascript高级编程学习笔记(43)—— 动态脚本
动态脚本 大多数情况下,DOM操作都很简洁明了 因为DOM主要就是用来操作页面中的可视节点的 但有些时候我们又希望可以动态的来进行DOM操作 其中的一部分也就是今天我们的内容动态脚本 动态脚本是什么意 ...
随机推荐
- 通过扩展让ASP.NET Web API支持W3C的CORS规范(转载)
转载地址:http://www.cnblogs.com/artech/p/cors-4-asp-net-web-api-04.html CORS(Cross-Origin Resource Shari ...
- Java Hour8
有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 本文作者Java 现经验约为7 Hour,请各位不吝赐教. Hour8 Jav ...
- wp8 入门到精通 LINQ to SQL
http://msdn.microsoft.com/zh-cn/library/bb397924.aspx LINQ 查询操作中的类型关系 (C#) 使用一个人类发明快速检索的方法 // Northw ...
- MATLAB学习笔记(五)——MATLAB绘图
(一)二维数据曲线图 一.绘制单根二维曲线 1.基本调用格式 plot(x,y) (1)x,y为长度相同的向量,分别用于储存x坐标和y坐标数据 (2)用于绘制以x,y为横,纵坐标的二维曲线. (3)举 ...
- C++primer学习笔记(四)——Chapter 6
6.1 Function Basics 一.函数的构造 type functionName( parameters list) statement 1.首先格式如上,一个函数一定要有返回值的类型ty ...
- lr数据库参数化取数:The query result is empty and same is the parameter file问题原因
出现这个问题的原因: 是因为我们的查询结果存在中文 如果查询结果没有中文,显示正常 解决办法: 新建一个数据源: 重新再选择这个数据源,再次查询: 说明不是连接字符串的问题或者是mysql驱动的问题 ...
- JVM的堆分配
为了展示虚拟机如何使用方法区中的信息,下面来举例说明: class Lava { private int speed = 5; void flow(){ } } public class ...
- 2016.7.9 计算机网络复习要点第四章之网际控制报文协议ICMP
1.ICMP允许主机或路由器报告差错情况和提交有关异常情况的报告:为了更有效地转发IP数据报和提高交付成功的机会: 2.ICMP不是高层协议,因为ICMP报文是装在IP数据报中的,作为其中数据部分,所 ...
- Xamarin Android长度单位区别
Xamarin Android长度单位区别 Android中长度单位有6种:px.in.mm.pt.dp/dip.sp.其中,px表示显示设备的一个像素:in表示显示设备的1英寸:mm表示显示设备的1 ...
- HealthKit开发教程之HealthKit的辅助数据
HealthKit开发教程之HealthKit的辅助数据 在HealthKit中除了主要数据之外,还有6个辅助数据分别为:体积类型数据.压力类型数据.时间类型数据.温度类型数据.标量类型数据和电导率类 ...