【www.arisingsemi.com--IT认证】

seting
LoadRunner 性能测试脚本
1  概述
Yoyo老师认为脚本录制编写是性能测试的一个重要环节。在性能测试过程中,虚拟用户模拟真实用户使用被测系统,
这个“模拟”的过程正是通过性能测试脚本来实现的。因此,编写一个准确无误的脚本对性能测试有至关重要的意义。
完成性能测试脚本包括两个步骤:脚本录制和脚本编写,本文重点关注脚本编写。

2  脚本录制
2.1.录制方式
HTTP协议脚本录制可选两种方式:基于HTML和基于URL。选择哪种录制方式的原则如下:基于浏览器的HTTP应用系统选择HTML,基于其他方式的HTTP应用系统选择URL。
2.2.录制注意点
取消录制期间自动关联功能;
如果部分测试脚本出现问题,需要重新录制,可以只录制存在问题的片断脚本,方法是不选中录制启动对话框中的Record the application startup。
3  脚本编写
3.1.常用技术
LoadRunner性能测试脚本编写常用的技术包括参数化,关联,逻辑控制和脚本模块化。

3.1.1.参数化
参数化就是将脚本中的常量转化为变量的过程。通过录制生成的脚本所有的数据都是常量,为了达到向服务器发送的数据多样化的目的,需要将一些数据常量转化为变量。
3.1.2.关联
关联就是查找动态数据,并把查询到的数据以参数的形式保存起来。在B/S或者C/S系统中,服务器返回给客户端的数据有些是动态改变的,例如客服系统的人工来话流水号和工作流系统的工单流水号。
当打开工单生成页面后,工单流水号已经从服务器端获取到了,而在提交工单步骤,需要将该流水号返回给服务器。因此,在提交工单之前,在脚本中必须获得流水号。
获得流水号的方法就是关联。
使用关联功能动态保存的参数跟直接通过参数化生成的参数是一致的。唯一不同的是,通过参数化生成的参数在脚本中可以高亮显示。
3.1.3.逻辑控制
业务系统在实际应用中,业务操作步骤间往往存在逻辑。
比如,客服3.0工作流系统,业务代表处理工单,如果待办区没有工单等待处理,则先从工单池中提取工单到待办区,然后进行处理,并且需要优先处理超时或即将超时的工单。在工单处理的性能测试脚本中,也必须遵从这种业务逻辑。

LoadRunner性能测试脚本采用C语言,因此脚本逻辑控制同C语言一致,使用if,switch,while/for/do控制结构。
3.1.4.脚本模块化
脚本模块化的目的是:提高脚本可读性、可重用性和脚本生产效率。脚本模块化的本质是抽取函数,一些很通用的函数甚至可以封装为DLL。模块化性能测试脚本的思想跟自动化测试的ActionWord有相似之处。

例如:客服3.0系统的登录功能,无论是工作流、知识库、公告便签还是培训考试,它们都使用相同的登录页面。我们可以把登录脚本抽取为一个函数csp_login(char *staffno,char * password),需要登录操作时,不需要录制和拷贝脚本,只要调用这个函数就可以了。
注意:并不是所有的脚本代码块都需要做模块化处理,只有那些稳定不变、并且经常用到的代码块才需要做模块化处理。不做得不偿失的事。
3.2.典型函数
LoadRunner中,常用的函数有很多,这里只介绍编写性能测试脚本过程中那些必然用到的函数。本文重点关注这些典型函数的应用场合及注意点,至于函数详细使用说明请参见LoadRunner帮助文档。
3.2.1.事务相关
3.2.1.1. lr_start_transaction/lr_end_transaction
功能:事务开始/结束标记。
应用场合:需要统计某一段代码块执行所需要的时间,这两个函数需要成对使用。

举例:工作流系统性能测试中有一个需求,300人在线,提交工单操作平均响应时间在3秒以内,则需要在提交工单请求步骤之前插入lr_start_transaction,提交工单请求步骤之后插入lr_end_transaction。
注意点:这两个函数只是标记函数,用于标记事务开始/结束,因此可以嵌套使用,即事务中还可以包
含子事务。

3.2.1.2. lr_think_time
功能:模拟思考时间,即等待时间。
应用场合:在线用户测试,为了让每一个虚拟用户模拟一个真实用户的行为,即让一个虚拟用户对系统产生的压力跟真实用户相当,就必须使用这个函数。这是因为,用户在使用系统的过程中,从一个操作转换到另一个操作,是需要时间的,这个时间就是思考时间。
举例:客服3.0工作流系统在线用户测试。对于工单查询操作,输入查询条件后提交查询,从输入查询条件至提交查询的时间间隔就是思考时间。因为LoadRunner无法模拟键盘输入的过程,它只能模拟键盘输入的等待时间,此时需要在提交查询的那个动作前插入lr_think_time函数。
注意点:在录制脚本中,原子事务内不要包含lr_think_time函数,否则该思考时间将被统计到事务响应时间中,造成结果不准确。另外lr_think_time是否启作用,可通过runtime-seting进行设置。

注:原子事务指那些不能再分割为更小事务的事务,它经常指一个单一的业务操作,通常表现为一个
URL请求。
3.2.1.3. lr_rendezvous
功能:在Vuser脚本中设置集合点。
应用场合:并发测试。

举例:客服3.0培训考试系统,100人同时打开同一份试卷。则需要在打开试卷的语句前插入lr_rendezvous函数,并在场景中设置集合点策略。
注意点:非并发测试,例如在测试系统的处理能力时,最好不要设置集合点,因为一旦设置了集合点,将导致一些VUser处于等待状态,在这等待过程中服务器将是空闲的,这将导致不能准确的测试出服务器的真实性能水平。
集合点更多用于发现系统的并发问题。
3.2.2.参数化/关联
_save_string/lr_save_int
功能:将某一字符串/整型保存为参数。
应用场合:有些变量的值通过C语言生成,之后在测试脚本中要使用这些变量。
举例:客服3.0业务配置台系统增加业务代表操作,业务代表的工号和姓名使用C语言函数生成。工号和
姓名分别保存在staff_no和staff_name变量中,则在脚本中可以使用lr_save_int(staff_no,"staffno"),lr_save_string(staff_name, "stafffname")将工号和姓名参数化。
注意点:无。
_reg_save_param
功能:在服务器返回的文本中查找一个或者多个字符串,并将搜索到的字符串值保存在参数中。
应用场合:在B/S或者C/S系统中,服务器返回给客户端的数据有些是动态改变的,在脚本的下一个步骤中,需要使用该动态数据。这时,就需要使用关联获得该动态数据。
举例:客服3.0工作流系统,工单办理每次都从待办区中打开第一条工单,为打开第一条工单,需要获取第一条工单的完整URL(包括URL中的parameter及其值),而每一次进入待办区,第一条工单有可能是不一样的。为获取第一条工单的URL,将打开工单的URL做关联。已知打开待办区操作获得的HTML有如下片断:

可在打开待办区的操作前插入如下语句:
web_reg_save_param("tt_url", "LB=javascript:openseviceforprocess("","RB=","false")",
"Ord=1","IgnoreRedirections=Yes", "Search=Body","RelFrameId=1", LAST );
运行脚本后,tt_url的值为:
/iwflow/?
serialNo=2008092200000033&serviceID=0099&nodeID=140004&dealID=2008092200000056&hisFlag=0&skill
ID=020401&dealSkillID=020101&dealStaff=1200
这个URL就是打开第一条工单的URL,有了URL,便可打开工单。

注意点:


(1)LoadRunner工具只能识别文本,在HTTP协议中只能识别HTML文档,因此关联的依据是HTML源码,而不是经过浏览器解析后的可视化文本。这一点很重要。


(2)关联还能将多个匹配的参数保存在数组中,方法是指定ORD的属性值为ALL,之后通过“{参数名_1}”, “{参数名_2}”, “{参数名_3}”格式可获得数组元素的值。



(3)该函数有一个属性NOTFOUND,默认值为ERROR,也就是说,如果找不到要查找的数据,将报出错误
,在必要的时候,例如脚本逻辑控制需要,可以将NOTFOUND的属性值设为WARNING,这样LoadRunner将不产生错误。
_save_searched_string
功能:在某一个字符缓冲区中搜索指定的字符串,并将搜到的字符串保存在参数中。
应用场合:可配合LoadRunner的关联功能,灵活获取服务器端返回的数据。
举例:客服3.0工作流系统,工单处理每次都从待办区中打开第一条工单,打开工单的URL已经通过关联
保存在tt_url参数中,在工单处理提交时,需要使用serviceNo,serviceID,nodeID,dealID,tt_url的值
如下:
/iwflow/?
serialNo=2008092200000033&serviceID=0099&nodeID=140004&dealID=2008092200000056&hisFlag=0&skill
ID=020401&dealSkillID=020101&dealStaff=1200
可使用以下函数保存serviceNo,serviceID,nodeID,dealID的值。

//保存serialNo,serviceID,nodeID,dealID参数
int getTTData(){
int i = 0;int j=0;。

本文来源:http://www.arisingsemi.com/it/55363/