51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 3332|回复: 7
打印 上一主题 下一主题

[原创] LR高级技巧实战

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2007-11-29 11:40:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
作者:徐林林  
某些网站把许老师的文章转载过去就变成了[ 来源:网络转截 | 作者:佚名 ] 1来是看不下去,2来好像没再论坛看到这片帖子就把他弄过来 希望能对大家有帮助

1.概述
        在山东BOSS性能压力测试过程中,发现脚本对于整个压力测试过程的重要性,一个压力测试脚本录制和编辑修改得怎么样直接影响后面压力测试的执行。通常情况下,脚本应尽可能的精简,就像写代码一样。针对BOSS系统的特点,个人认为把单一业务录制成一个Action,并在脚本中添加Transaction,Find检查(可以采用URL-based scrīpt 方式录制并事先设定),Rendezvous,参数化等基本元素,然而有时我们会发现光有这些基本元素还不能满足我们的要求。比如在Controller中运行我们的脚本时,一旦压力过大或某种原因导致某一业务失败,而此时我们很想尽快地找出错误的原因。当然此时我们第一想到的是,查找日志,但是有时发现查找日志很不方便,因此我们希望寻求一种更快捷的方式,希望能直接从Controller的Errors错误中找到出错的服务号码、在第几次Iteration的哪个Transaction出错。实现的方式,当然是通过简单的编程来调用错误日志里的信息,另外本文中还简单介绍了关于LoadRunner工具使用的一些常用注意事项、脚本处理技巧和一些常用性能参数的分析及性能测试中机器瓶颈的定义和查看机器瓶颈的相关命令。
        下面再具体的一一介绍。

2.一个规范的性能测试脚本就像一段规范的程序代码一样,需要基本的说明信息:
在下面要介绍的脚本中,我把这些信息以注释的形式放在vuser_init最前面:
/*
@corporation:Copyright By *** Technologies CO.,LTD. All Rights Reserved.
@Athour:XuLinLin
@Date:2005-09-18
@Name:异地缴费压力测试脚本
@Parameter:BOSSURL,LogName,PhoneNum,iteration,FanHui
@Data:BOSSURL:BOSSURL.dat; //由于BOSS压力测试前台展现环境多,故将地址也参数化。
LogNameogName.dat; //登录用操作员,选择具备异地缴费权限的操作员,这里选择的是德州操作员300个。
PhoneNumhoneNum.dat; //用于异地缴费的服务号码,这里选择的是烟台的正常在用的标准全球通号码3000个。
iteration:iteration.dat; //用于压力测试出错时,打印出错所在的循环次数。
@Descrīption:此脚本用于测试异地缴费的性能及稳定性,选用德州的操作员对烟台的标准全球通号码进行异地缴费,目标是
通过vuser模仿真实操作员进行异地缴费,达到验证或测试系统性能和稳定性的目的。
@Notes:脚本的录制使用的是LoadRunner8.0的VU,采用的是URL-based scrīpt方式,需要特别注意的是Recording Options(按Ctrl+F7)
的Advanced 选项里的Surport Charset一般情况默认为不选,除非字符集合采用的是国际标准才选中UTF-8选项,否则会出现汉字乱码现象。
*/

[ 本帖最后由 岁月童话 于 2007-11-29 11:43 编辑 ]
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

2#
 楼主| 发表于 2007-11-29 11:40:58 | 只看该作者
3.通常情况下,任何业务必须在登陆成功后才能做,所以有必要对登陆成功与否进行判断:
下面我从脚本中取出相关部分进行简单介绍:
vuser_init()
{
int status; //定义变量用于判断登陆是否成功
web_reg_find("Text=山东移动BOSS",
LAST);
…….
…….
web_submit_data("reguserAction.do", //登陆提交数据Action。
"Action=http://{BOSSURL}/boss/reguserAction.do",
"Method=POST",
"RecContentType=text/html",
"Referer=http://{BOSSURL}/boss/index.jsp",
"Snapshot=t12.inf",
"Mode=HTTP",
ITEMDATA,
"Name=logname", "Value={LogName}", ENDITEM,
"Name=password", "Value=", ENDITEM,
LAST);
status = web_submit_data("reguserAction.do", // 取成功与否标志
"Action=http://{BOSSURL}/boss/reguserAction.do",
"Method=POST",
"RecContentType=text/html",
"Referer=http://{BOSSURL}/boss/index.jsp",
"Snapshot=t12.inf",
"Mode=HTTP",
ITEMDATA,
"Name=logname", "Value={LogName}", ENDITEM,
"Name=password", "Value=", ENDITEM,
LAST);

if (status == LR_FAIL) //一旦登陆失败,脚本给出提示报错信息。
{
lr_error_message("错误信息: %s", "不能正常登陆!");
return -1;
}
}

.事务的定义,很简单,也很有必要,尽量是每个定义的事物符合逻辑和小。
在下面的脚本中,在异地缴费这一业务中定义了两个Transaction:准备异地缴费数据和提交异地缴费,见如下脚本代码:
lr_start_transaction("准备异地缴费数据");


web_set_max_html_param_len("4096");
……….
web_submit_data("chargeacc.do",
"Action=http://{BOSSURL}/boss/charge/commonbusiness/acccharge/chargeacc.do?act=queryaccount",
"Method=POST",
"RecContentType=text/html",
"Referer=http://{BOSSURL}/boss/charge/commonbusiness/acccharge/acccharge.jsp?act=first",
"Snapshot=t74.inf",
"Mode=HTTP",
ITEMDATA,
"Name=isconfirm", "Value=no", ENDITEM,
"Name=chargetype", "Value=telnumber", ENDITEM,
"Name=telnumber", "Value={PhoneNum}", ENDITEM,
"Name=nowfee", "Value=0.0", ENDITEM,
"Name=factfee", "Value=", ENDITEM,
"Name=totalfee", "Value=0.0", ENDITEM,
LAST);
lr_end_transaction("准备异地缴费数据", LR_AUTO);

5.增强脚本,对脚本进行简单的编程。
增强脚本,对脚本进行简单的编程,为性能或压力测试提供方便,这也是写
本文的宗旨,下面对此做简单的介绍:
        5.1首先,定义成功与否的判断标志或字符串。
        在此,我把判断成功与否的标志定义在异地缴费Action 最前面,具体定义如下:char fanhuiflag[30]="操作业务数据成功!";
但是大家可能会问,字符串"操作业务数据成功!"从何处而来,可以肯定的不能凭空想象,成功标志可从两三种方式来取得:
第一种:也是最简单的一种,直接从脚本中取得,具体操作是以View Tree 方式找到相关的界面,然后从Server Response的Snapshot的Body里去取。见下面的图片:
注:Snapshot在录制前要将Recording Options>Advanced里的Save snapshot resources locally 选项选中。




        第二种方式,从脚本代码中去取,即取find函数中相关字符串,具体做法是,找到在提交事件前的web_reg_find函数,然后从中取相关字符串。
web_reg_find("Text=---------操作业务数据成功!--------",
LAST);
值得注意的是要有web_reg_find函数,可以在录制前选中Recording Options>Advanced里的Generate web_reg_find functions for page titles 选项。


        第三种方式,从本地的snapshot里去取,具体操作,首先找到提交数据事件相关脚本,找到snapshot文件的名称,然后从本地的data文件里去找这个snapshot文件,然后丛中找到我们需要的字符串。
web_reg_find("Text=---------操作业务数据成功!--------",
LAST);
…….
web_submit_data("chargeacc.do_3",
"Action=http://{BOSSURL}/boss/charge/commonbusiness/acccharge/chargeacc.do?act=submit&atype=commitdata",
"Method=POST",
"RecContentType=text/html",
"Referer=http://{BOSSURL}/boss/charge/commonbusiness/acccharge/chargeacc.do?act=querycustomer",
"Snapshot=t129.inf",
"Mode=HTTP",
ITEMDATA,
"Name=isconfirm", "Value=no", ENDITEM,
"Name=chargetype", "Value=telnumber", ENDITEM,
"Name=telnumber", "Value=", ENDITEM,
"Name=nowfee", "Value=8.8", ENDITEM,
"Name=factfee", "Value=0.00", ENDITEM,
"Name=totalfee", "Value=8.8", ENDITEM,
"Name=accountno", "Value={WCSParam_Diff1}", ENDITEM,
"Name=factpay", "Value=8.8", ENDITEM,
"Name=grantpercent", "Value=", ENDITEM,
"Name=grantfee", "Value=0", ENDITEM,
"Name=takecash", "Value=8.8", ENDITEM,
"Name=zero", "Value=0", ENDITEM,
"Name=paytype", "Value=Cash", ENDITEM,
"Name=remark", "Value=", ENDITEM,
"Name=invoice", "Value=joininvoice", ENDITEM,
LAST);

5.2设置和保存判断成功与否的参数,这也是最关键的地方。
有一点大家都很清楚,业务成功返回的字符串和失败返回的字符串是不同的,我们所要做的是将返回的字符串做为参数保存下来,然后拿这个参数和我们事先定义好的成功的标志做比较,有两种方式可以设置和保存这一参数,下面简单介绍:
第一种方式也是最准确的方式,是以View Tree 方式找到相关的界面,然后从Server Response的Snapshot的Body里的成功的返回标志,然后对其进行Create Parameter,这样LoadRunner会自动在脚本中添加web_reg_save_param函数,具体如下:
// [WCSPARAM WCSParam_Text2 24 操作业务数据成功!_Text2] Parameter {WCSParam_Text2} created by Correlation Studio
web_reg_save_param("WCSParam_Text2",
"LB=---------",
"RB=-",
"Ord=1",
"RelFrameId=1",
"Search=Body",
LAST);


        第二种方式是在提交事件前添加web_reg_save_param函数,具体操作是在提交事件前右击鼠标选择Insert Before 选项,然后在弹出的对话框中选择Services里的web_reg_save_param选项,单击OK按纽,然后在弹出的对话框中输入相关的数据。




        5.3 编写相关判断代码段。
        在已经定义好判断字符串和设置和保存好成功与否的标志字符串参数后,编写相关判断代码段,这也是最关键的地方,具体代码段如下:
if (strcmp(fanhuiflag,lr_eval_string("{WCSParam_Text2}"))!=0)
{
lr_error_message("消息: %s,在第 %s 次循环时出错,出错号码:%s", "提交异地缴费数据失败!", lr_eval_string("{iteration}"), lr_eval_string("{PhoneNum}"));
}
简单解释如下:
fanhuiflag:前面已经定义好的成功标志字符串的数组名,当然前面也可以用指针来实现,这里不做介绍。
WCSParam_Text2:为实现设置和保存好的成功与否返回的字符串的参数;
PhoneNum:服务号码的参数化,具体为电话号码。关于参数化,这里不做分析和解释部分。
Iteration:为了定位具体的循环而设置的参数。
Strcmp函数:LoadRunner自带的字符串比较函数,相等时返回0
lr_eval_string函数:LoadRunner自带求字符串函数,函数格式为
char * lr_eval_string (const char * instring );
(另一种判断方式:先事先定义好int rc=1; char *fanhuiflag="操作业务数据成功!";然后在定义事务的结尾进行判断: rc=strcmp(str_tip,lr_eval_string("{re_str_tip}"));
if(rc==0)
{
lr_end_transaction("异地缴费_提交", LR_PASS);
}
else
{
lr_error_message("异地缴费_提交失败,号码为:%s",lr_eval_string("{msisdn}"));
lr_end_transaction("异地缴费_提交", LR_FAIL);
}
//lr_end_transaction("异地缴费_提交",LR_AUTO);)

        5.4验证我们的需求是否实现
        下面简单介绍,整个验证过程,在确保脚本正确和测试环境正常的情况下,我们先在VU里验证下是否真正实现了我们想要的功能,为了方便,我特地将判断条件该为==而不是!=,通过查看日志来检查。

        首先,选中菜单栏里的Run-time Settings子菜单,设置里面的Log选项,选中Enable Logging 和Always send messages 和Extended log 及Parameter substitution。
设置Run Logic 里的Number of Iterations 为2,然后运行,并查看日志。可以得到如下的日志(只取了关键部分的):
第一次循环关键部分:
YiDiJiaoFei.c(598): Notify: Transaction "提交异地缴费数据" ended with "Fail" status (Duration: 4.8459 Wasted Time: 0.0060).
YiDiJiaoFei.c(605): Notify: Parameter Substitution: parameter "WCSParam_Text2" = "操作业务数据成功!"
YiDiJiaoFei.c(607): Notify: Next row for parameter iteration = 1 [table = iteration].
YiDiJiaoFei.c(607): Notify: Parameter Substitution: parameter "iteration" = "1"
YiDiJiaoFei.c(607): Notify: Parameter Substitution: parameter "PhoneNum" = "13953555588"
YiDiJiaoFei.c(607): Error: 消息: 提交异地缴费数据失败!,在第 1 次循环时出错,出错号码:13953555588

第二次循环关键部分:
YiDiJiaoFei.c(598): Notify: Transaction "提交异地缴费数据" ended with "Fail" status (Duration: 4.2347 Wasted Time: 0.0064).
YiDiJiaoFei.c(605): Notify: Parameter Substitution: parameter "WCSParam_Text2" = "操作业务数据成功!"
YiDiJiaoFei.c(607): Notify: Next row for parameter iteration = 2 [table = iteration].
YiDiJiaoFei.c(607): Notify: Parameter Substitution: parameter "iteration" = "2"
YiDiJiaoFei.c(607): Notify: Parameter Substitution: parameter "PhoneNum" = "13953572390"
YiDiJiaoFei.c(607): Error: 消息: 提交异地缴费数据失败!,在第 2 次循环时出错,出错号码:13953572390

        下面验证执行时,能正确找到出错的号码信息,将脚本加入到场景后,同样设置好Run-time Settings。

        设置结果保存路径等相关信息,按Start Scenario 执行场景,等出错是单击右上角的Errors,然后选中错误信息再按Details按纽查看错误信息。
回复 支持 反对

使用道具 举报

该用户从未签到

3#
发表于 2007-11-29 21:38:23 | 只看该作者
好帖子 ,相当有实战经验 学习了 .
但是 今天通过用 WEB_REG_FIND  发现 LR 的函数 很郁闷,因为在HTML 有" 号, LR的脚本不认这个.(不能识别HTML的",)
于是
LR_REG_SAVE_PARAM 也不能成功,字符验证 也不行 郁闷 .
有没好的解决方法?
回复 支持 反对

使用道具 举报

该用户从未签到

4#
发表于 2007-12-4 16:22:25 | 只看该作者
好文章,楼主妹妹是否是Langchao的?
回复 支持 反对

使用道具 举报

该用户从未签到

5#
发表于 2007-12-27 13:21:45 | 只看该作者
回复 支持 反对

使用道具 举报

  • TA的每日心情
    开心
    2015-11-5 15:12
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]测试小兵

    6#
    发表于 2007-12-27 14:23:39 | 只看该作者

    回复 3# 的帖子

    "前面家转意符....
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2015-11-5 15:12
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]测试小兵

    7#
    发表于 2007-12-27 14:24:03 | 只看该作者
    帖子不错,顶下...
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    8#
    发表于 2007-12-27 14:25:33 | 只看该作者
    怎么论坛这个帖子都出现4次了。。。。。。。。
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-16 13:05 , Processed in 0.096838 second(s), 27 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表