




已阅读5页,还剩16页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
LR脚本编写规范LR脚本编写规范(V1.0.0)文档修订历史版本号日期描述维护人V 1.0.02011-04-17初稿王颖第 2 页 共 21 页目录LR脚本编写规范3n1. 命名规则3脚本命名规则3Action命名规则4事务命名规则4请求命名规则4参数命名规则5n2. 脚本结构说明5n3. 请求说明6n4. 优化规则6LR脚本编写规范n 1. 命名规则脚本命名规则LR脚本需存放于英文目录结果中,避免脚本在后续执行中出现异常,为方便管理脚本的命名规则需遵循以下原则: 简单准确的概括当前脚本的业务功能; 可以是英文描述或是功能拼音首字母组合; 全部脚本命名规则需统一;举例: 信用卡还款,脚本名称可以是CreditCardPayment或xykhk。Action命名规则Action的命名规则只是针对于默认生成的Action和自己手动添加的action来说的,需遵循以下原则:(1)Vuser_init: action名称不需要修改;(2)默认生成的Action和自己手动添加的action: 以“项目简称_业务简称”命名每个业务action;举例:CEB_xykhk; 业务名称尽量与脚本名称统一;(3)如需单独存放脚本中使用函数,新建action命名为:Action_lib;(4)Vuser_end: action名称不需要修改;(5)Globals.h: 名称不需要修改;事务命名规则考虑到事务是结果中关注点的特殊性,为方便查看结果事务的命名需遵循以下原则: 事务名称需以中文命名,明确表述业务功能;举例:本行转账_第一次请求,或信用卡还款; 若一个功能需多次请求,每个请求需封装成一个事务,每个事务以精简的语言描述对应的动作;举例:比如明细查询的功能需要经过3个步骤,首先选择账户列表,然后列出每个账户中的余额,然后点击每个账户对应的明细链接,进入明细查询结果界面。这个过程涉及到提交3个请求,每个请求可命名为:账户列表查询,余额查询,明细查询;原因:虽然每个请求都封装成一个事务,但用户真正想得到相应时间等指标的却可能是其中某个请求的数据,这时我们可以将前面的其他事务放到初始化中,然后将对应的事务注释掉,方便统计任意一个请求的数据。请求命名规则每个业务可能都需要提交多次请求才能最终实现一个完整功能,为了清晰了解每个业务的请求数,每个请求的命名需遵循以下原则: 以“ceb_业务简称_请求序号”命名每个请求;举例:ceb_xykhk_1,ceb_xykhk_2; 若一个功能需多次请求,每个请求名称和对应的事务名称可以准确的描述出第*次请求是完成了什么功能;举例:比如“我的账户”模块中的明细查询功能需要经过3个请求,第一个请求(ceb_wdzh_1)完成了(账户列表查询)事务的功能,第二个请求(ceb_wdzh_2)完成了(余额查询)事务的功能,第三个请求(ceb_wdzh_3)完成了(明细查询)事务的功能参数命名规则参数的命名考虑到两种种情况,一种是在脚本编写过程中需要方便传递过程变量自己定义的参数,一种情况是需要从服务器返回报文中解析出来然后再组合数据串用于向服务器提交请求的参数,所以对应参数的命名可以分两种种情况: 对于第一种情况:比如服务器返回内容可记为Response; 对于第二种情况:比如需要从服务器返回的报文中取到某个参数,直接用对应的参数名称;举例:CardNo,PayAmount,action对应的url可记为ceb_xykhk_3url;概括的说,就是每个参数都需要简单准确的表达变量的功能。n 2. 脚本结构说明每个脚本都由基本的3个action和一个globals.h文件组成,如需单独存放脚本中使用函数,可新建action命名为:Action_lib。 对于vuser_init:由于初始化在执行场景中只需要执行一次,一般包含以下内容:(1) 宏定义(#define)常量定义,包含地址,证书路径,算法,消息类型等;(2) 脚本中使用到的变量,结构函数及实体对象;(3) 初始化函数:A. 加载外部的dll文件;B. 为之前定义的变量分配合适大小的内存;C. EWP访问地址;D. 添加报文头信息;E. 握手及前期准备获得加解密的密钥串;F. 凡是在需要关注的事务之前的一切操作都可以放在初始化中,在第一次脚本编写过程中可仅将登录放在初始化中;G. 函数成功返回标志,Return 0; 对于业务action:(1) 对于场景执行前的调试脚本,可将全部业务相关脚本放在主action中,具体执行场景时将业务其他脚本放入初始化中;(2) 每次请求之前需明确列出请求地址,提交参数,接口名称;(3) 拼接提交串后需将转LR_ENC_SYSTEM_LOCALE为LR_ENC_UTF8;(4) 提交串需加密,有时需转URL编码;(5) 基本结构为:注册函数-发请求(转码)-判断返回结果中的错误串-没有错误串进行解码查找内容-给出脚本执行正确的提示 每个块结构加上注释说明,方便阅读; 对于函数action:存放脚本中使用的函数; 对于vuser_end:存放需要释放的变量; 对于globals.h: 存放需要引入的头文件,头文件需放在LR安装目录的include中;n 3. 请求说明每个请求之前都需对本次请求做说明,内容包括: 请求说明: *业务第*次请求; 请求url:【http:/HostAdress/ceb_s/prelogin?app=ceb&o=i】; 提交数据:参数名:*,【固定数据】,参数数据; 接口方法:【*】 注意:对于个别参数名称不能明显看出的,比如用n表示userid,我们特别需要指出;举例:/* 信用卡还款业务第3次请求请求url:【http:/HostAdress/atompub_s/form/gdb_xyk_bills?app=ceb&o=i】 提交data:body=CardNo: 信用卡号【lr_eval_string(account_in)】AcctNo: 还款帐号【lr_eval_string(account_out)】Org:币种(人民币)【102】PayAmount:还款金额【1】OTPPassword:手机动态密码【111111】OTPPassType:短信、阳光令牌【SMS】otherFlag:自己的卡【Y】n:接口方法【PayCreditCardResult.do?】*/n 4. 优化规则脚本基本规则在上述内容中已经明确,但在具体项目中会得到一些经验性的优化规则,主要有以下几点: 在解析XML内容时,尽量用描述性编程,比如:lr_xml_get_values(XML=content2, ValueParam=PayerAcNo, Query=/form/inputname=PayerAcNo/value, NotFound=Continue, LAST);;避免使用Query=/form/input2/value,否则在数据结构改变后脚本经常会出现问题; 每个事务的结果都置成LR_AUTO,后边需手工指定在什么情况应该是lr_set_transaction_status(LR_FAIL),否则事务成功率统计将不准确; 如果要统计某个业务的某个请求的响应时间及其他指标时,需将对应请求之前的操作放入初始化中; 对于可参数化的数据尽量用参数化表示,比如登录数据等,避免每次都在脚本中修改; 在对某个请求进行关注时,将脚本中的其他封装的事务全部注释掉,避免统计太多事务,给用户理解结果时照成障碍; 对于上下文中取数据的,但在调试过程中经常需要参照的数据,可在脚本中注释,方便每次进行脚本修改时调试; 每个脚本最后应该根据检查点来给出是否正确执行的结果; 注意脚本中退出的控制,初始化中应该是退出虚拟用户,在action中应该是退出本次循环,但对于放在初始化中的业务脚本就保留原来的循环控制; 每个请求之前需正确添加思考时间,否则影响后边事务的成功率; 对于像交易密码需要(先加密-拼串-加密)还是(拼串-加密)的情况要给出注释说明情况; 服务器返回内容为空的检查;n 4. 脚本编写原则 脚本结构为:Vuser_initICA_loginICA_bhzz_brzhVuser_endGlobals.h说明: 全部业务脚本都放在同一个脚本中,以不同的Action封装,每个业务Aciton以项目简称_模块名_业务名,比如登录可以省略模块名。当调试其中某个脚本时可通过运行时设置只运行其中某个脚本。 初始化中包含一次登录脚本,目的是某些业务需在登录后才能进行。这样方便进行登录与登录内业务进行混合场景运行。 将初始化action中的握手事务注释掉,业务action中的事务命名方式为:业务名称_第*次请求,也需将事务起始,事务结果成功与失败注释掉,只需保留需要进行性能测试的脚本,并将事务命名为业务名称,方便结果查看。 全部测试事务都需进行结果成功失败的判断。 需要在每个项目中调整的变量或参数有:EWP服务器地址,APP名称,密码加密方式,证书与DLL文件的存放路径,测试与调试脚本日志输出标志。 握手,握手后的解析,加密函数,界面函数,字符串替换,验签等都放在头文件中。 对于事务Action来说,去掉collist list还让channel run的请求,若完成这个业务只需最后一个请求就可以完成,那我们就在业务Action中只保留最后一个请求,原则是只要能保证脚本正常请求成功即可。 编写完脚本后需将脚本循环至少2次,以保证脚本是否正常运行,因为有时脚本中提交的数据是写死的,比如相同的确认界面如果业务上不允许提交两次,我们就需要想办法,比如可以利用新数据(利用前序步骤),或者用参数化。 对于每个业务Action,只需对测试的请求进行内容验证,比如出现什么字样才算请求通过,对于其他的请求只保证没有ERROR出现即可。 每个请求前,利用lr_save_string函数,将地址和参数列出来,然后利用sprintf函数将参数用%s形式读进去,为了是每次参数发生变化时方便修改,可增加参数含义说明。 握手可不必进行ERROR的判断,因为握手不会出现返回内容错误的时候,最多也就是请求服务器地址失败,导致没有返回内容。 在初始化中任何请求若发生错误,需使用lr_exit(LR_EXIT_VUSER, LR_FAIL);函数将当前虚拟用户退出,否则在跑场景的时候action中循环的请求肯定会连带全部出错。 业务Action中若请求发生错误要用lr_exit(LR_EXIT_ITERATION_AND_CONTINUE , LR_FAIL);函数,退出当前循环并继续,否则也会出现连带错误。n 4. 脚本参考l Vuser_initvuser_init()lr_save_string(78:80,HostAdress);/78:80,1:9008lr_save_string(ica,AppName); lr_save_string(HandShakeClient(),ClientHelloBody);web_reg_save_param(response,LB=,RB=,Search=Body,LAST);web_reg_save_param(response_len,LB=Content-Length: ,RB=rn,Search=Headers,LAST);web_reg_save_param(emp_cookie,LB=Set-Cookie: ,RB=; path=,Search=Headers,LAST);/lr_start_transaction(握手);web_custom_request(EMP_HandShake, Method=POST, URL=http:/HostAdress/user/handshake?ota_version=AD-UMP-1.1.1-000000&app=AppName&o=i, RecContentType=application/octet-stream,Body=ClientHelloBody, LAST);/lr_end_transaction(握手, LR_AUTO);Response_1=HandShakeServer(lr_eval_string(response_len),lr_eval_string(response);lr_save_string(Response_1,response);if(LOG_FLAG)lr_convert_string_encoding(lr_eval_string(response),LR_ENC_UTF8 , LR_ENC_SYSTEM_LOCALE, response2);lr_message(握手返回结果【%s】n,lr_eval_string(response2);len = RSA_GetPublicKeyFromCert(NULL, 0, APP_CERT, 0);result = RSA_GetPublicKeyFromCert(PublicKey_JMJ, len, APP_CERT, 0);if(result!=220)lr_error_message(未正确加载公钥证书,请查看是否正确设置n,);lr_exit(LR_EXIT_VUSER, LR_FAIL);/=登录_第一次请求=memset(Data1,0,10240); lr_save_string(02,encryptMode); EncryptPwd(Data1,lr_eval_string(PassWord),strlen(lr_eval_string(PassWord),PublicKey_JMJ,lr_eval_string(encryptMode); lr_save_string(Data1,pinData.pin); web_convert_param(pinData.pin, SourceEncoding=HTML,TargetEncoding=URL, LAST); sprintf(Data1,Language=zh_CN&loginName=%s&pinData.pin=%s,lr_eval_string(LoginName),lr_eval_string(pinData.pin); lr_convert_string_encoding(Data1,LR_ENC_SYSTEM_LOCALE,LR_ENC_UTF8 ,BODY); memset(Data2,0,10240);Aes_On(Data2,lr_eval_string(BODY),ClientKey,ClientIV);AddHMac(Data2,strlen(Data2),ClientMac,20);lr_save_string(Data2,POSTBODY);web_reg_find(Search=body,SaveCount=ErrorCount,Text=nerror string=,LAST);web_reg_save_param(response,LB=,RB=,Search=Body,LAST);/lr_start_transaction(登录);web_custom_request(ICA_login, Method=POST, URL=http:/HostAdress/phone_s/login?app=AppName&o=i, RecContentType=text,Body=POSTBODY, LAST);if (atoi(lr_eval_string(ErrorCount) != 0)/lr_end_transaction(登录, LR_FAIL);lr_convert_string_encoding(lr_eval_string(response),LR_ENC_UTF8 , LR_ENC_SYSTEM_LOCALE, response);lr_error_message(登录返回错误:【%s】n,lr_eval_string(response);lr_exit(LR_EXIT_VUSER, LR_FAIL);else /lr_end_transaction(登录, LR_PASS);if(LOG_FLAG)sprintf(Response,%s,lr_eval_string(response);memset(Response_2,0,10240);Aes_Off(Response_2,Response,ServerKey,ServerIV);lr_save_string(Response_2,response);lr_convert_string_encoding(Response_2,LR_ENC_UTF8 , LR_ENC_SYSTEM_LOCALE, response2);lr_message(初始化登录请求:点击登录按钮,返回:【%s】,lr_eval_string(response2);result = lr_xml_get_values(XML=response, ValueParam=content, Query=/feed/entry/content, NotFound=Continue,LAST);if(result = 0 )lr_convert_string_encoding(lr_eval_string(response),LR_ENC_UTF8 , LR_ENC_SYSTEM_LOCALE, response2);lr_error_message(#事务错误:未取到content。【%s】n,lr_eval_string(response2);lr_exit(LR_EXIT_VUSER, LR_FAIL);result1 = (char *)strstr(lr_eval_string(response2), 证券服务);if (result1 != NULL ) lr_message(登录正确执行!n);return 0;l ICA_loginICA_login()/=登录_第一次请求= memset(Data1,0,10240); lr_save_string(02,encryptMode); EncryptPwd(Data1,lr_eval_string(PassWord),strlen(lr_eval_string(PassWord),PublicKey_JMJ,lr_eval_string(encryptMode); lr_save_string(Data1,pinData.pin); web_convert_param(pinData.pin, SourceEncoding=HTML,TargetEncoding=URL, LAST); sprintf(Data1,Language=zh_CN&loginName=%s&pinData.pin=%s,lr_eval_string(LoginName),lr_eval_string(pinData.pin); lr_convert_string_encoding(Data1,LR_ENC_SYSTEM_LOCALE,LR_ENC_UTF8 ,BODY); memset(Data2,0,10240);Aes_On(Data2,lr_eval_string(BODY),ClientKey,ClientIV);AddHMac(Data2,strlen(Data2),ClientMac,20);lr_save_string(Data2,POSTBODY);web_reg_find(Search=body,SaveCount=ErrorCount,Text=nerror string=,LAST);web_reg_save_param(response,LB=,RB=,Search=Body,LAST);lr_start_transaction(登录);web_custom_request(ICA_login, Method=POST, URL=http:/HostAdress/phone_s/login?app=AppName&o=i, RecContentType=text,Body=POSTBODY, LAST);if (atoi(lr_eval_string(ErrorCount) != 0)lr_end_transaction(登录, LR_FAIL);lr_convert_string_encoding(lr_eval_string(response),LR_ENC_UTF8 , LR_ENC_SYSTEM_LOCALE, response);lr_error_message(登录返回错误:【%s】n,lr_eval_string(response);lr_exit(LR_EXIT_ITERATION_AND_CONTINUE , LR_FAIL);else lr_end_transaction(登录, LR_PASS);if(LOG_FLAG)sprintf(Response,%s,lr_eval_string(response);memset(Response_2,0,10240);Aes_Off(Response_2,Response,ServerKey,ServerIV);lr_save_string(Response_2,response);lr_convert_string_encoding(Response_2,LR_ENC_UTF8 , LR_ENC_SYSTEM_LOCALE, response2);lr_message(第一次请求:点击登录按钮,返回:【%s】,lr_eval_string(response2);result = lr_xml_get_values(XML=response, ValueParam=content, Query=/feed/entry/content, NotFound=Continue,LAST);if(result = 0 )lr_convert_string_encoding(lr_eval_string(response),LR_ENC_UTF8 , LR_ENC_SYSTEM_LOCALE, response2);lr_error_message(#事务错误:未取到content。【%s】n,lr_eval_string(response2);lr_exit(LR_EXIT_ITERATION_AND_CONTINUE , LR_FAIL);result1 = (char *)strstr(lr_eval_string(response2), 证券服务);if (result1 != NULL ) lr_message(登录正确执行!n);return 0;l ICA_bhzz_brzhICA_bhzz_brzh()/=本行转账_本人账户第一次请求= lr_save_string(/atompub_s/form/ica_zzhk_brzh/LP1004?app=ica&o=i,ICA_bhzz_brzh_1url);lr_save_string(21#0000861530010372,debitAcc);lr_save_string(00#0000861502207854,registeredOwnAccount);lr_save_string(00,transferCCY);lr_save_string(100,transactionAmount);lr_save_string(1,opFlag);lr_save_string(0,tempData);lr_save_string(1,accountType);lr_save_string(2,pkgId);lr_save_string(20240715,transferDate);lr_save_string(brzh,icaChannelId);lr_save_string(1,icaId);lr_save_string(执 行,submit2);sprintf(Data1,debitAcc=%s®isteredOwnAccount=%s&transferCCY=%s&transactionAmount=%s&opFlag=%s&tempData=%s&accountType=%s&pkgId=%s&transferDate=%s&icaChannelId=%s&icaId=%s&submit2=%s,lr_eval_string(debitAcc),lr_eval_string(registeredOwnAccount),lr_eval_string(transferCCY),lr_eval_string(transactionAmount),lr_eval_string(opFlag),lr_eval_string(tempData),lr_eval_string(accountType),lr_eval_string(pkgId),lr_eval_string(transferDate),lr_eval_string(icaChannelId),lr_eval_string(icaId),lr_eval_string(submit2);lr_convert_string_encoding(Data1,LR_ENC_SYSTEM_LOCALE,LR_ENC_UTF8 ,POSTBODY);memset(Data2,0,10240); Aes_On(Data2,lr_eval_string(POSTBODY),ClientKey,ClientIV);AddHMac(Data2,strlen(Data2),ClientMac,20);lr_save_string(Data2,POSTBODY);web_reg_find(Search=body,SaveCount=ErrorCount,Text=nerror string=,LAST);web_reg_save_param(response,LB=,RB=,Search=Body,LAST); /lr_start_transaction(本行转账_第一次请求);web_custom_request(ICA_bhzz_brzh_1, Method=POST, URL=http:/HostAdressICA_bhzz_brzh_1url, RecContentType=text, Body=POSTBODY, LAST);if (atoi(lr_eval_string(ErrorCount) != 0)/lr_end_transaction(本行转账_第一次请求, LR_FAIL);lr_convert_string_encoding(lr_eval_string(response),LR_ENC_UTF8 , LR_ENC_SYSTEM_LOCALE, response); lr_error_message(第一次请求,点击执行按钮,返回错误:【%s】n,lr_eval_string(response);lr_exit(LR_EXIT_ITERATION_AND_CONTINUE , LR_FAIL);else /lr_end_transaction(本行转账_第一次请求, LR_PASS);if(LOG_FLAG)sprintf(Response,%s,lr_eval_string(response);memset(Response_2,0,10240);Aes_Off(Response_2,Response,ServerKey,ServerIV);lr_save_string(Response_2,response);lr_convert_string_encoding(Response_2,LR_ENC_UTF8 , LR_ENC_SYSTEM_LOCALE, response2);lr_message(第一次请求,点击执行按钮,返回:【%s】,lr_eval_string(response2);/=本行转账_本人账户第二次请求=lr_save_string(/atompub_s/form/ica_zzhk_brzh?app=ica&o=i,ICA_bhzz_brzh_2url);lr_save_string(3,pkgId);lr_save_string(1,icaId);lr_save_string(2,opFlag);lr_save_string(1,pinData.pinSessKey);lr_save_string(Trans?tranCode=mobileTransferWithinBankOp,n);lr_save_string(mobileTransferWithinBankOp,dse_operationName);sprintf(Data1,pkgId=%s&icaId=%s&opFlag=%s&pinData.pinSessKey=%s&n=%s&dse_operationName=%s,lr_eval_string(pkgId),lr_eval_string(icaId),lr_eval_string(opFlag),lr_eval_string(pinData.pinSessKey),lr_eval_string(n),lr_eval_string(dse_operationName);lr_convert_string_encoding(Data1,LR_ENC_SYSTEM_LOCALE,LR_ENC_UTF8 ,POSTBODY);memset(Data2,0,10240);Aes_On(Data2,lr_eval_string(POSTBODY),ClientKey,ClientIV);AddHMac(Data2,strlen(Data2),ClientMac,20);lr_save_string(Data2,POSTBODY);web_reg_find(Search=body,SaveCount=ErrorCount,Text=nerror string=,LAST);web_reg_save_param(response,LB=,RB=,Search=Body,LAST);lr_start_transaction(本行转账_本人账户);web_custom_request(ICA_bhzz_brzh_5, Method=POST, URL=http:/HostAdressICA_bhzz_brzh_2url, RecContentType=text,Body=POSTBODY, LAST);if (atoi(lr_eval_string(ErrorCount) != 0)lr_end_transaction(本行转账_本人账户, LR_FAIL);lr_convert_string_encoding(lr_eval_string(response),LR_ENC_UTF8 , LR_ENC_SYSTEM_LOCALE, response);lr_error_mess
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安保部加班管理制度
- 安全科人员管理制度
- 定向钻施工管理制度
- 实训室库房管理制度
- 审计科印章管理制度
- 客车线路牌管理制度
- 家为乐餐饮管理制度
- 家装修施工管理制度
- 应急处置卡管理制度
- 强电房安全管理制度
- DB61-T 5068-2023 钢桥面改性聚氨酯混凝土铺装应用技术规程
- 国内民用船舶修理价格表(92黄本)
- 国家中长期科技发展规划纲要2021-2035
- 中学生早餐调查报告公开课一等奖课件省赛课获奖课件
- 【解析】江西省新余市2023年小升初语文试卷
- TACEF 077-2023 污染地块风险管控与修复工程职业健康防护指南
- 2023-2024学年四川省阿坝州小学语文四年级期末深度自测试卷详细参考答案解析
- 高等量子力学-课件
- 上消化道出血急救和护理演示文稿
- 公路箱梁水纹产生及防治
- 通许县供水管网工程环境影响报告
评论
0/150
提交评论