| 网站首页 | 测试咨讯 | 新手入门 | 专注性能 | 测试技术 | 测试管理 | 测试工具 | 开发社区 | 工具下载 | 资料下载 | 测试论坛 | 

[CNTester联盟群]交流群:34446273/21968356/64461572 白盒群:18400216 自动化群:2706508 性能群:4498858 外包群:59649884 管理群(需有管理经验):64442523

新手入门
 入门指南
 经验之谈
测试咨讯
 行业新闻
 网站动态
 人才就业
 CNTester基金
 标准规范
专注性能
 性能测试知识
 性能测试工具
 程序设计性能
 数据库性能
 Web应用服务器性能
 操作系统性能
 服务器与网络性能
测试技术
 用例设计
 性能测试
 自动化测试
 Web测试
 面向对象测试
 综合技术
 阶段性测试
 行业类测试
测试管理
 项目管理
 项目案例
 质量管理
 软件过程
测试工具
 Mercury系列
 Rational系列
 测试管理工具
 性能测试工具
 功能测试工具
 单元测试工具
 其它测试工具
开发社区
 Java技术
 DotNet技术
 C技术
 数据库技术
 操作系统
 服务器与中间件
工具下载
 测试工具
 开发工具
 企业工程
 网络通信
 媒体桌面
 游戏娱乐
 其他工具
资料下载
 测试资料
 程序设计
 数据库
 操作系统
 应用服务器
 电子期刊
 其他资料
 
 
您现在的位置: 中国测试员网站 >> 专注性能 >> 性能测试工具 >> Loadrunner >> 文章正文
  [推荐]LR高级技巧实战         ★★★★ 【字体:
LR高级技巧实战
LR高级技巧实战
作者:yxd2006    文章来源:转贴    点击数:    更新时间:2007-6-20    

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压力测试前台展现环境多,故将地址也参数化。
LogName:LogName.dat; //登录用操作员,选择具备异地缴费权限的操作员,这里选择的是德州操作员300个。
PhoneNum:PhoneNum.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选项,否则会出现汉字乱码现象。
*/

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;
}
}

4.事务的定义,很简单,也很有必要,尽量是每个定义的事物符合逻辑和小。
在下面的脚本中,在异地缴费这一业务中定义了两个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按纽查看错误信息。

 

原贴地址:http://www.51testing.com/?action_viewnews_itemid_13834.html

文章录入:yxd2006    责任编辑:yxd2006 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
     
    最新热点 最新推荐 相关文章
    · mysql优化基础
    · MySQL服务器安装完之后如何调节性能
    · Mysql数据库管理系统优化方案
    · MySQL Performance Tuning Primer Script
    · MySQL 性能跟踪语句
    · Linux 和对称多处理
    · 应用与数据库性能测试解决方案,QUEST SO
    · 负载、性能测试和容量测试的关系和区别
    · LoadRunner监控Windows和Linux常见问题
    · 31个用来测试网站各项性能的免费工具
    · 应用与数据库性能测试解决方案,QUEST SO
    · 研究项目: JBoss架构分析
    · 如何通过 20% 的工作获得 80% 的性能改善
    · Linux 调度器内幕
    · 在 Linux 上利用数据分区功能提高可伸缩性
    · 降低 Linux 内存开销
    · Linux 和对称多处理 在 SMP 系统上发挥 L
    · 如何提高系统性能指标
    · Java 优化技术 充分挖掘 Java 应用程序性
    · 高速缓存和连接池对访问数据库性能的影响
    31个用来测试网站各项性能的
    研究项目: JBoss架构分析
    Rational LoadTest 性能测试
    loadrunner 负载测试计划
    IBM Rational助您轻松完成基
    如何通过 20% 的工作获得 80
    基于 WebSphere Application
    Linux 调度器内幕
    在 Linux 上利用数据分区功能
    使用异步 I/O 大大提高应用程
     
     
     
    ======> [CNTester联盟群]交流群:34446273/21968356/64461572 白盒群:18400216 自动化群:2706508 性能群:4498858 外包群:59649884 管理群(需有管理经验):64442523
    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 | 

    Copyright@2007 by CNTester.com 中国测试员网站 桂ICP备07005590

    本站为开源免费网站,非商业赢利性组织。本站文章部分从网络搜索获取,如果您认为某些侵犯了您的权益,麻烦您联系本站,我们会尽快删除相关内容,同时也希望您的谅解,我们的初衷是为了让更多人去学习这方面的知识,让行业有更好的发展。

    联系电话: 15021358905