LoadRunner自动化测试工具.docx
《LoadRunner自动化测试工具.docx》由会员分享,可在线阅读,更多相关《LoadRunner自动化测试工具.docx(22页珍藏版)》请在冰点文库上搜索。
LoadRunner自动化测试工具
第一部份:
Loadrunner的简介
LoadRunner是一种预测系统行为和性能的工业级标准性能测试负载测试工具.通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题,LoadRunner能够对整个企业架构进行测试.通过使用LoadRunner,企业能最大限度地缩短测试时间,优化性能和加速应用系统的发布周期.
目前企业的网络应用环境都必须支持大量用户,网络体系架构中含各类应用环境且由不同供应商提供软件和硬件产品.难以预知的用户负载和愈来愈复杂的应用环境使公司时时担心会发生用户响应速度过慢,系统崩溃等问题.这些都不可避免地导致公司收益的损失.MercuryInteractive的LoadRunner能让企业保护自己的收入来源,无需购置额外硬件而最大限度地利用现有的IT资源,并确保终端用户在应用系统的各个环节中对其测试应用的质量,可靠性和可扩展性都有良好的评价.
LoadRunner是一种适用于各种体系架构的负载测试工具,它能预测系统行为并优化系统性能.LoadRunner的测试对象是整个企业的系统,它通过模拟实际用户的操作行为和实行实时性能监测,来帮助您更快的查找和发现问题.此外,LoadRunner能支持广泛的协议和技术,为您的特殊环境提供特殊的解决方案.
安装注意事项
LR的版本:
目前常见的:
,,,每个版本差别蛮大的,大家尽量使用高版本.本文以为例.
操作系统选择:
LR是个比较底层的软件,OS最好为Windows2000,因为W2k的稳定性和兼容性都不错,需要的内存也低,有人把LR装在WinXp下面,是有问题的.出错现象:
"应用程序正常初始化(0xc0000005)失败".在win2003,winXP下安装LR后会出现如此情况.
License问题:
LR的license是区分类型的,一般是按协议和时间,用户数量来区分的,比如:
LicenseforLoadRunner(Type:
Global500,TimeLimited时效:
1年)就表示支持所有协议,最大500VU,时间:
1年.
三种安装类型:
StandaloneInstallation,NetworkInstallation,NetworkInstallationandshortcuts
四种安装方式:
TypicalInstallation,LoadGenerator,MIListener,CustomInstallation
我们根据实际情况选择,我用StandaloneInstallation和CustomInstallation安装,安装所有组件.
协议的选择或者VUSER类型的选取
我现在要用LoadRunner测一个C/SorB/S系统,请问该用什么协议
经常有新手问:
为什么我用LR录完之后VuGen里产生不了脚本这就是协议选择的问题了,LR支持的协议和应用非常广泛,很少有人能用完这么多协议,我们就常见的大多数人用的加以讨论:
B/S系统:
选择Web(Http/Html),
C/S系统:
根据C/S结构所用到的后台数据库来选择不同的协议,如果后台数据库是Sybase,则采用sybaseCTlib协议,如果是Sqlserver,则使用MSSqlserver的协议,至于oracle数据库系统,当然就使用oracle2-tier协议.
对于没有数据库的c/s(ftp,SMTP)这些可以选择windowssockets协议.
至于其他的ERP,EJB(需要,选择相应的协议即可.
LR的基本原理
LR启动以后,在任务栏会有一个Agent进程,通过Agent进程,监视各种协议的Client与Server端的通讯,用LR的一套C语言函数来录制脚本,所以只要LR支持的协议,就不会存在录制不到的,这是它与Loadtest,WR,Robot(Gui)录制脚本的很大一个区别.(WR必须识别对象,才能录制到).然后LR调用这些脚本向服务器端发出请求,接受服务器的响应.至于服务器内部如何处理,它不关心.
测试脚本录制/分配所遵循的几个原则
脚本越小越好.就像写code一样的,不要太长,尽量做到一个功能(Transaction)一个脚本.如果那些功能是连续有序的,必须先做上一个,才能工作下一个,那就只好放在一起了.
选择使用频率最高的.有些人喜欢在LR中测试几乎所有的功能,其实这样不合适,我们把最常用的,使用频率最高的,拿出来测试.但是也要结合用户实际使用情况,一般在一个系统中是多个用户使用多个功能,某些功能使用的频率更大一些,我们在录制脚本之前就要设计好,哪个脚本会跑几个用户,一共需要多少个脚本,能满足性能测试的需求.
选择你所需要的进行录制.对于WEB的程序,对于你所关注的内容没什么影响的操作,你可以不录制,可以使用暂停,这需要试的,对被测功能有一个清楚的认识和了解,要能把握住哪些地方是对整个过程没有影响的,比如一些查询,通常,选择条件的页面都可以不录制,但对于一些页面有可能要传递参数,就需要录制了,如何确定哪些点可以不录制,一是可以找开发人员了解清楚程序设计的结构,再就是靠自己的经验,作的多了,就心中有数了.
例子:
Testcasename
Vusernumber
Total50
Vusernumber
Total20
Iteration
Testcase1:
merchantscreatescheduleandcostingsheet
10
4
200
Testcase2:
Merchantrunreport-5concurrentusers(3merchants,2vendors).
5
1
200
Testcase3:
merchanteditcostingsheetFOBandcreateproductionschedule
9
4
200
Testcase4:
merchantreplyscheduletasks
6
3
300
Testcase5:
vendorreplyscheduletasks
7
3
200
Testcase6:
vendoreditcostingsheet
7
3
200
Testcase7:
merchantcreatetopic,vendorreplytopic
4
1
100
Testcase8:
importsreplyscheduleanddoclassification.
2
1
10
第二部分:
录制脚本
录制脚本前需要理解的几个基本概念
事务(Transaction)
事务(Transaction)是这样一个点,我们为了衡量某个action的性能,需要在action的开始和结束位置插入这样一个范围,这就定义了一个transaction,LoadRunner运行到该事务的开始点时,LoadRunner就会开始计时,直到运行到该事务的结束点,计时结束.这个事务的运行时间在结果中会有反映.
插入事务操作可以在录制过程中进行,也可以在录制结束后进行.LoadRunner可以在脚本中插入不限数量的事务.
举个例子:
比如一个单据,把从登录到保存成功退出整个作为一个脚本,对于需要关注的保存时间,定义为单独的事务,以取得响应时间,事务脚本函数如下:
集合点(Rendezvous)
集合点:
是一个并发访问的点,在测试计划中,可能会要求系统能够承受1000人同时提交数据,在LoadRunner中可以通过在提交数据操作前面加入集合点,这样当虚拟用户运行到提交数据的集合点时,LoadRunner就会检查同时有多少用户运行到集合点,如果不到1000人,LoadRunner就会命令已经到集合点的用户在此等待,当在集合点等待的用户达到1000人时,LoadRunner命令1000人同时去提交数据,并发访问的目的.
注意:
集合点经常和事务结合起来使用,常放在事务的前面,集合点只能插入到Action部分,vuser_init和vuser_end中不能插入集合点.集合点函数如下,参数不能加空格:
加入集合点之后,在后面运行过程中可以看到VU的状态,会等待集合.
IPSpoofer(IP欺骗)
当运行场景时,虚拟用户使用它们所在的LoadGenerator的固定的IP地址.每个LoadGenerator上(同时)运行大量的虚拟用户(*不明白),这样就造成了大量的用户使用同一IP同时访问一个网站的情况,这种情况和实际运行的情况不符,并且有一些网站会限制同一个IP的登陆.为了更加真实的模拟实际情况,LoadRunner允许运行的虚拟用户使用不同的IP访问同一网站,这种技术称为"IP欺骗".
启用该选项后,场景中运行的虚拟用户将模拟从不同的IP地址发送请求.该选项非常
的有用.注意:
IPSpoofer在连接LoadGenerators之前启用.要使用IP欺骗,各个LoadGenerator机器必须使用固定的IP,不能使用动态IP(即DHCP).
IPWizard工具就提供了生成多个ip的功能,IPWizard是一个单独的程序,我们可以在开始菜单里面找到,你可以添加一个局域网内的IP段.添加后重启,在Win2k下使用Ipconfig/all查看到很多虚拟的IP,最后要在Controller里面选择enableipspoofer.
检查和contentscheck点
对于查询类的脚本,一定要添加检查点,以保证在测试时结果的正确性.因为LR只要检测到网页的响应,就认为是pass而并不管当前网页内容的正确性.在进行压力测试时,为了检查Web服务器返回的网页是否正确,VuGen允许我们插入Text/Imag检查点,这些检查点验证网页上是否存在指定的Text或者Image,还可以测试在比较大的压力测试环境中,被测的网站功能是否保持正确.检查点的含义和WinRunner中的检查点功能基本上一致,这里就不再作过多的说明.
举个例子:
当我用loadrunner做压力测试的时候,
它的确能反馈给我各种服务器性能的数据,
但是在做B/S结构系统的测试的时候,
却发现如下问题:
loadrunner不能正确判断操作是否成功,
比如登录,我要测试200人同时登录,
但是我的里面没有正确的关闭数据库的连接,
导致登录100人后,建立了100个数据库连接,
第101人一个人登录的时候,由于超出数据库连接的最大数,
所以,jsp程序抛出了一个数据库异常.
但是页面的走向是正确的,所以loadrunner会认为程序是正确执行的,但是事实却并非如此.
对于有的页面是无法添加文本和图像检查点的,就加入contentscheck点.
LR脚本复用问题
作为一款优秀的负载测试工具,LR的测试脚本有很好的复用性,参数化后的脚本,在应用没什么大的变化的情况下,一直是可以用的.甚至你在A服务器录制的脚本,如果做测试的时候,需要转移到B服务器上,你只需要用查找替换的功能将A服务器的IP地址换成B服务器的IP地址就可以使用.
理解Correlation(关联)
关联是用来解决脚本中存在的动态数据问题的.在中,当你回放一次后,LR会自动录找你录制的时候和回放时候的差别,找出动态数据,并作成参数.举个我作的动态数据的例子,当用户登录时,会产生一个Sessionid号,访问结束后,该Sessionid便会失效.我录制的时候,在脚本里面获取到了该Sessionid,但当我再回放的时候,这个Sessionid已经无效了,所以我需要把这个Sessionid作为一个动态数据,当我一登录的时候,便获取一个新的有效的Sessionid,然后通过函数把它保存下来
web_reg_save_param("WCSParam_Text2",
"LB=ProcessID=",
"RB=;",
"Ord=1",
"RelFrameId=1",
"Search=body",
LAST);
那么后面用到的页面中就可以调用WCSParam_Text2这个参数使用这个新的Sessionid号.这是个动态数据很典型的例子,
web_submit_data("",
"Action=",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html",
"Referer=",
"Snapshot=",
"Mode=HTML",
ITEMDATA,
"Name=hdclentip","Value=chenjing",ENDITEM,
"Name=hdProcessID","Value=F8E5ACCD372845C38C7E1981A342F703",ENDITEM,
"Name=selInstanceid","Value=T01",ENDITEM,
"Name=TxtUserID","Value={RYBH}",ENDITEM,
"Name=TxtPassword","Value=cwpass",ENDITEM,
"Name=Txtkjdate","Value=",ENDITEM,
"Name=selInstancetxt","Value=性能测试用(中型数据库)",ENDITEM,
"Name=selInstance","Value=T01",ENDITEM,
LAST);
web_url("",
"URL=ProcessID={WCSParam_Text2}",
"TargetFrame=",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=",
"Mode=HTML",
LAST);
理解web_reg_save_param函数,
intweb_reg_save_param(constchar*ParamName,,LAST);
第一部分:
参数名字,用双引号括起,逗号分开;
第二部分:
ListofAttributes,包括:
LB,RB,RelFrameID,Ord,Search,SaveOffset,SaveLen等,
第三部分:
LAST,结束标志.
左边界,右边界到底是个什么概念
LB是左边界,要查找的字符串左面的边界值,即位于查找字符串的最左边的字符串,RB是右边界,要查找的字符串右面的边界值,即位于查找字符串的最右边的字符串,比如说吧,程序中有这么一个赋值,ProcessID=A53625E18440FCE81F26DCE712E65EBA;如果ProcessID的值是动态的,我想使用动态变量,那我设定查找左边界为LB=ProcessID=,右边界为RB=;的字符,如果找到了,就替换成变量.
Search是指查找范围,就是说在哪里查找这些值,可以取这样几个值,我们一般设为ALL,Body等即可.
Headers(Searchonlytheheaders),
Body(searchonlyBodydata,notheaders),
Noresource(searchonlythehtmlbody,excludingallheadersandresources),
ALL(searchBodyandheaders).ThedefaultvalueisALL.
RelFrameID:
ThehierarchyleveloftheHTMLpagerelativetotherequestedURL.一般取1
ORD:
Thisparameter,alsoknownasInstance,indicatestheordinalorinstanceofthematch.一般取1
已经为用户定义好了很多类型的关联,我们可以自己定义Newrule,不过我在录制脚本的时候一般把系统的那些都关掉,定义自己的,只是有的时候,它不能自动关联,就干脆手工作了.需要关联的地方:
一般是在有主键,不允许记录重复,和一些主程序中传递过来的参数,在后面要用到等情况才使用关联的,你可以先执行一遍,如果有些地方不允许重复,参数值无效,就会出错的,根据错误提示你可以判断出来,就知道需要关联了.一般需要关联的不多,我现在遇到的就是进程号,以及表的主键.我这里有个Correlation的官方文档,大家下去可以自己看看.
2.1.8以录制Web(Http/Html)协议为例讲述一下LR的脚本的录制
LR的脚本是C语言代码,LR有自己的一整套函数接口,可以供外部调用,在VUGen里面敲Lr_就可以看到了.Web(Http/Html)脚本本身分INIT,ACTION,END三部分,各部分的解释:
INIT部分可以理解为初始部分,ACTION可以理解为事务部分,也是测试的主体,END是退出结束.重复的时候,仅重复action部分.我们一般把登录部分放在init,退出放到end,只会执行一次,或者有的时候,各部分反复的次数不一样,分成多个action,可以单独设定反复次数.(如果需要在登陆操作设集合点,那么登陆操作也要放到Action中,因为vuser_init中不能添加集合点)
Init,login
#include""
#include""
vuser_init()
{
于浏览器的应用程序推荐使用HTML-basedScript,脚本中采用
HTML页面的形式来表示,这种方式的Script脚本容易维护,容易理解,使用该选项中的advance中的第一个选项,如果单纯的HTML方式,是不允许使用关联的.
2.不是基于浏览器的应用程序推荐使用URL-basedScript,脚本中的表示采用基于URL的方式,不是很好阅读.
解释:
1.是否记录录制过程中的ThinkTime,如果记录,还可以设置最大值,一般我不记录这个值.
2.通知Vugen去重新设置每个action之间的Httpcontext,缺省是需要的.
3.完整记录录制过程的log,
4.保存一个本地的snapshot,可以加速显示
5.把html的title放到web_reg_find函数里面
6.支持的字符集标准
header的录制,我们采用缺省即可,不需要用web_add_header去录制非标准的header信息.
对录制的content的内容进行filter,不作为resource处理的.
解释:
这个就是我前面提到的关联,系统已经预先设置好了一些常见的关联rules,我们录制脚本之前,可以把系统的都关掉,定义自己的,只是有的时候,它不能自动关联,就干脆手工关联.这里比较重要,我还有一个专门的PPT文档是详细讲这个的,大家可以到我的网站上下载.
脚本录制
现在可以开始录制脚本了,我给出几段已经录制好的脚本.
lr_rendezvous("createpreproductionschedule");
lr_start_transaction("createpreproductionschedule");
web_url("",
"URL=",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=",
"Mode=HTML",
LAST);
web_url("",
"URL=forwardID=1",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=",
"Mode=HTML",
LAST);
个函数的解释:
intweb_url(constchar*Name,constchar*url,,
[EXTRARES,,]LAST);
这个函数load指定的web页面.
*Name:
页面的name;
url:
页面的url,Resource:
指示theURL是否是一个资源.0,不是,1,是.
RecContentType:
录制脚本过程中,Header响应的类型,.text/html,application/x-javascript
Referer–参考web页的theURL
Snapshot-snapshot文件名(扩展名inf),correlation的时候要的.
Mode–录制的级别:
HTMLorHTTP
Last-属性列表的结束标志.
intweb_submit_data(constchar*StepName,*StepName:
这里有个例子,theweb_submit_datafunctionsubmitsaformusingthePOSTmethod:
web_submit_data("",
"Action=",
"Method=POST",
"TargetFrame=",
"EncType=multipart/www-urlencoded"
"RecContentType=text/html"
ITEMDATA,
"name=flight","value=6593",ENDITEM,
"name=reserveFlight","value=Next>",ENDITEM,
LAST);
脚本的参数化
如果用户在录制脚本过程中,填写提交了一些数据,比如创建一个新的document.这些操作都被记录到了脚本中.当多个虚拟用户运行脚本时,都会提交相同的记录,这样做会被应用禁止,会出错,这样也不符合实际的运行情况,而且有可能引起冲突.为了更加真实的模拟实际环境,需要各种各样的输入.参数化输入是一种不错的方法
参数化包含以下两项任务:
①在脚本顶用参数取代常量值.
②设置参数的属性和数据源.
参数化仅可以用于一个函数中的参量.你不能用参数表示非函数参数的字符串.另外,不是所有的函数都可以参数化的.
我举一个例子来说明,还是我上面那个脚本,
web_submit_form("",
"Snapshot=",
ITEMDATA,
"Name=PTName","Value=performance0001",ENDITEM,
"Name=headerTempID","Value=preProductionHeaderTemplate",ENDITEM,
"Name=selectHeader","Value=1",ENDITEM,
"Name=schTempID","Value=preProductionDetailTemplate",ENDITEM,
LAST);
因为每次创建文档的时候,需要用不同的名字,系统禁止同名,如果同名就会出错,所以要把PTName值参数化,我们只要选中"performance0001",然后点鼠标右键,选择"Replacewithaparameter.",出现以下窗口:
参数类型解释:
nDateTime:
很简单,在需要输入日期/时间的地方,可以用DateTime类型来替代.其属性设置也很简单,选择一种格式即可.当然也可以定制格式.
nGroupName:
暂时不知道何处能用到,但设置比较简单.在实际运