LoadRunner性能测试系统学习教程:Vuser发生器(上)

引言

Vuser发生器(VisualUserGenerator,简称为VuGen)主要通过捕获客户端向服务器发送的HTTP请求,将这些请求录制成脚本,在回放时将捕获的HTTP请求再次发送,以达到模拟客户的行为的目的,所以Vuser主要是用来捕获最终用户业务流程和创建自动化测试脚本,即生成测试脚本。VuGen是录制测试脚本、编辑与完善测试脚本的一个平台,支持C语言语法。

主要包括以下内容:

脚本录制

Recording Options设置

Run-Time Settings设置

脚本完善

脚本录制

启动VisualUserGenerator,创建一个新的脚本,开始录制脚本,在录制脚本过程中,VuGen会自动捕获操作过程中客户端与服务器端进行通信的所有数据。这里涉及的关键点是如何选择录制协议。  

脚本开发主要包括四大步骤:计划、录制脚本、脚本增强和单机调试脚本,如图所示。

 

 

如何选择协议

在创建一个新的脚本时,首先会弹出一个对话框,在该对话框中选择录制时需要的协议,这步非常重要,选择的协议将直接影响到录制后的脚本是否理想,如何选择录制协议是录制前必须要解决的问题。  

各种协议和相关头文件的对应关系如图所示。  

协议

头文件

AJAX(Click&Script)

web_ajax.h

Citrix

ctrxfuncs.h

COM/DCOM

lrc.h

Database

lrd.h

FTP

mic_ftp.h

General C function

lrun.h

IMAP

mic_imap.h

LDAP

mic_midap.h

MAPI

mic_mapi.h

Oracle NCA

orafuncs.h

POP3

mic_pop3.h

ROP

lrrdp.h

SAPGUI

as_sapgui.h

SAP(Click&Script)

sap_api.h

Siebel

lrdsiebel.h

SMTP

mic_smtp.h

Terminal Emulator

lrrte.h

WAP

as_wap.h

Web(HTML\HTTP)

as_wab.h

Web(Click&Script)

web_api.h

Web Services

wssoap.h

Windows Sockets

lrs.h

 

选择协议的常用方法主要有以下几种:  

1.最简单的方法就是向开发工程师确认数据通信所采用的协议,因为开发工程师最清楚应用程序采用的是何种通信协议。  

2.没有开发工程师支持时,可以通过概要或详细设计手册获知所使用的协议。  

3.使用协议分析工具捕获通信时的数据包并进行分析,然后确定被测对象所使用的协议。在使用协议分析工具分析协议过程中一定要摒除底层协议,不要被底层协议所迷惑。  

4.根据以往测试经验来判断被测试对象采用的协议,这种方法具有猜测性,有时候不一定准确。  

在LoadRunner新的版本中有一个协议分析的工具(ProtocolAdvisor),通过该工具可以分析当前系统所使用的协议。协议分析工具的使用步骤如下:  

1.在【WelcometotheVirtualUserGenerator】界面单击【ProtocolAdvisor】按钮,如图所示。

 

 

2.弹出【ProtocolAdvisor】对话框,如图所示。

 

 

Applicationtype:选择应用程序的类型,被测试的应用程序类型主要包括两类:InternetApplictions和Win32Applications,也即通常说的B/S和C/S框架的两类应用程序。  

Programtoanalyze:分析的程序,如果选择的应用程序类型为InternetApplications那么,该选项为MicrosoftInternetExplorer,即IE浏览器,因为LoadRunner在录制时默认启动IE浏览器进行录制;如果选择的应用程序类型为Win32Applications,那么该选项为需要测试的应用程序的路径。  

URLAddress:即需要分析的网页地址;  

Workingdirectory:工作目录,默认的为LoadRunner所在路径的bin目录。  

3.设置待分析程序的路径或URL地址,单击【OK】按钮,即开始分析应用程序,通常分析一个简单的业务即可停止分析。  

4.单击浮动框中的【StopAnalyzing】按钮,停止分析应用程序,并产生分析后的结果。  

LoadRunner提供了多种协议,具体的协议分类见表。

 

 

1.单协议脚本:创建单协议Vuser脚本,在对话框中选择录制时需要的协议,如图所示。创建新脚本时,会弹出一个对话框,LoadRunner提供三种选择协议的方式:单协议脚本、多协议脚本和最近使用过的协议。  

 

 

2.多协议脚本:创建多协议Vuser脚本。在AvailableProtocols中选择一个或多个协议,点击右箭头,将其移入到SelectedProtocols部分中,同样,在SelectedProtocols中选择一个或多个协议,点击左箭头可以移除选中的协议,如图所示。

 

 

3.最近使用过的协议:从最近录制脚本的协议列表中,选择一种协议进行录制,如图所示

 

 

开始录制脚本  

协议选择好后可以开始录制脚本。这里以Web(HTTP/HTML)协议为例进行录制。  

VuGen录制浏览器主要是通过代理的方式来实现的。开始录制时,VuGen打开浏览器(默认使用Mircosoft自带的IE浏览器,使用其它浏览器录制容易出现HTTP请求被丢失的现象,所以尽量使用IE浏览器进行录制),并以VuGen作为代理来访问目标服务器。这样,VuGen就可以捕获客户端与服务器之间通过的数据包,如图所示。

 

 

在使用VuGen进行录制用户操作时,VuGen会对捕获的数据进行分析,并将其还原成对应协议的由API组成的脚本。同时,VuGen会将这些函数生成的脚本插入到VuGen编辑器中,以创建原始的Vuser脚本。  

录制时系统弹出一个录制窗口,如图所示。

 

 

在URLAddress中输入要录制的站点地址。RecordintoAction选项表示将录制的代码放到哪个部分。LoadRunner生成的代码由三部分组成:vuser_init、Action和vuser¬_end。  

注意:一般情况下都是将生成的代码放在Action部分,因为vuser_init和vuser¬_end两部分的代码只会执行一次,这样会出现这种问题,客户的并发虚拟用户只执行一次,执行完成一次后再也不执行,这样就没有HTTP请求给服务器,也即服务器没有压力。如下例子,图是每秒点击率的值。

 

 

从图中可以看出,在场景执行到25秒后,客户端的点击率为0,即25秒后客户端没有提交任何请求,这就是典型的由于将脚本放在vuser_init引起的,因为脚本放在vuser_init中,导致每个虚拟用户只会执行一次这部分的脚本,当用户加载完成后,再也不行,所以看到后期的点击率都为0。  

Recordtheapplicationstartup选项表示应用程序一旦启动,VuGen就立即开始录制;如果不选中,应用程序启动后,VuGen会弹出如图所示的对话框,并且暂时不会进行录制,当用户操作应用程序到需要录制的地方时,点击Record按钮,VuGen才开始录制。默认情况下Recordtheapplicationstartup是选中的状态。点击Record按钮开启录制。

 

 

在录制前还需要注意在RecordinOptions设置对话框中,设计脚本录制的方式,关于脚本的录制方式将在3.2.1小节中详细介绍。  

开始录制后,会出现如图所示的工具栏 

 

 

该工具条从左到右依次代表开始录制、暂停录制、停止录制、新建Action、在脚本与录制界面之间切换、添加开始事务标识、添加结束事务标识、设置集合点和添加注释。  

录制过程中,LoadRunner会自动记录用户的操作。录制完成后,点击“停止录制”按钮结束录制,这时VuGen会自动生成一个脚本,如图所示。

 

 

这是一个比较简单的脚本,但可以看出LoadRunner生成的脚本都是由函数组成。

Recording Options设置

在进行录制时,首先要对录制的一些参数进行设置,只有将这些参数设置好,才能录制并生成需要的脚本。  

首先是RecordingOptions设置,需要注意的设置项有:Recording选项卡、Advanced选项卡和Correlation选项卡。  

在Tools菜单中选择RecordingOptions或直接按快捷键Ctrl+F7进入参数设置对话框,如图所示。

 

 

Recording选项卡

在RecordingOptions对话框中,选择Recording选项卡。RecordingLevel包含两种录制模式:HTML-basedscript和URL-basedscript,如图所示,默认情况下选中HTML-basedscript录制方式。当然,两种录制模式也存在差别  

 

 

单击【HTMLAdvanced…】按钮,弹出【AdvancedHTML】对话框,如图所示,在该对话框中关于HTML-basedscript脚本方式又有两种:“Ascriptdescribinguseractions”和“Ascriptcontainingexplicit”。

 

 

Ascriptdescribinguseractions:模拟用户行为录制,即GUI录制,把用户每一步的操作显示出来,最后生成的脚本非常直观并且会将上下文的一些敏感信息记录下来。它创建URL(web_url)、link(web_link)、image(web_image)和提交表单(web_submit_form)。  

下面以Ascriptdescribinguseractions方式录制一个登录的功能,录制后的代码如下:  

web_url("WebTours",  

"URL=http://127.0.0.1:1080/WebTours/",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=",  

"Snapshot=t1.inf",  

"Mode=HTML",  

LAST);  

lr_think_time(4);  

web_submit_form("login.pl",  

"Snapshot=t2.inf",  

ITEMDATA,  

"Name=username","Value=test1",ENDITEM,  

"Name=password","Value=1",ENDITEM,  

"Name=login.x","Value=65",ENDITEM,  

"Name=login.y","Value=8",ENDITEM,  

LAST);  

return0;  

从生成的代码中可以看到,在录制时只做了两个操作,生成的代码也只有两个函数,也即这种录制模式只录制用户的操作,其它的内容不会被录制。使用的提交信息函数为web_submit_form()。  

AscriptcontaningexplictURLsonly:录制所有links(链接)、images(图片)和URL(web_url),但不创建web_link、web_image和提交表单(web_submit_form)。这种录制方式生成的脚本不直观。  

下面以AscriptcontaningexplictURLSonly方式录制一个登录的功能,录制后的代码如下:

web_url("WebTours",  

"URL=http://127.0.0.1:1080/WebTours/",  

"TargetFrame=",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=",  

"Snapshot=t1.inf",  

"Mode=HTML",  

LAST);  

web_submit_data("login.pl",  

"Action=http://127.0.0.1:1080/WebTours/login.pl",  

"Method=POST",  

"TargetFrame=body",  

"RecContentType=text/html",  

"Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",  

"Snapshot=t2.inf",  

"Mode=HTML",  

ITEMDATA,  

"Name=userSession","Value=108748.859052248ffQDHzQptDHfDDfzcpzVzzcf",ENDITEM,  

"Name=username","Value=test1",ENDITEM,  

"Name=password","Value=1",ENDITEM,  

"Name=JSFormSubmit","Value=off",ENDITEM,  

"Name=login.x","Value=53",ENDITEM,  

"Name=login.y","Value=10",ENDITEM,  

LAST);  

return0; 

从生成的代码中可以看到,同样的提交登录的信息但使用的函数为web_submit_data(),不再以表单的方式提交,而web_submit_form()函数则是以表单的信息进行提交的,该函数运行时,首先在页面上去查找表单,再提交数据,而web_submit_data()则不需要,直接向服务器发送要提交的数据。  

但在录制过程中很可能会录制到一些非HTML的元素(如Java小程序、XML、ActiveX元素、JavaScript),这些非HTML元素主要用于包含或去获取自己的一些资源,例如,JavaScript的JS文件用于调用加载多个图片。对于这类非HTML的元素,录制时有三种方式:  

Recordwithinthecurrentscriptstep:在录制时对于非HTML资源并不会生成一个新的功能。它列出所有相关资源的参数,如web_url、web_link和web_submit_data。这些web功能的参数使用EXTRARES标示。  

如以下代码: 

web_url("index.asp",  

"URL=http://www.daisy.com/index.asp",  

"TargetFrame=",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=",  

"Snapshot=t2.inf",  

"Mode=HTML",  

EXTRARES,  

"Url=http://www.daisy.com/ScrollApplet.class","Referer=",ENDITEM,  

"Url=http://www.daisy.com/board.txt","Referer=",ENDITEM,  

"Url=http://www.daisy.com/nav_login1.gif",ENDITEM,  

...  

LAST);  

Recordinseparatestepsanduseconcurrentgroups:在一个组中记录这些单独的步骤,为每个非HTML资源创建一个新的功能(但不包括一些页面的功能,如web_url、web_link等)。所有的web_url资源都将放置并行组中(并行组由web_concurrent_start和web_concurrent_end进行标示)。  

如以下代码: 

web_url("index.asp",  

"URL=http://www.daisy.com/index.asp",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=",  

"Snapshot=t2.inf",  

"Mode=HTML",  

LAST);  

web_concurrent_start(NULL);  

web_url("ScrollApplet.class",  

"URL=http://www.daisy.com/ScrollApplet.class",  

"Resource=1",  

"RecContentType=application/octet-stream",  

"Referer=",  

LAST);  

web_url("board.txt",  

"URL=http://www.daisy.com/board.txt",  

"Resource=1",  

"RecContentType=text/plain",  

"Referer=",  

LAST);  

web_concurrent_end(NULL);  

Donotrecord:不记录,对于非HTML元素不记录。  

注意:使用HTML-Based模式录制时,VuGen插入目标帧到web_url函数中时,VuGen会在run-time运行的浏览器中和结果报告中显示页面的正确性。  

如以下代码:

web_url("buttonhelp.gif",  

"URL=http://www.hplab.com/home?com/rstr?BV_EngineID...,  

"TargetFrame=main",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=http://www.hplab.com/home?...  

"Snapshot=t5.inf",  

"Mode=HTML",  

LAST); 

URL-basedscript方式:将每条客户端发出的请求录制成一条语句,对LoadRunner来说,在该模式下,一条语句只能建立一个到服务器的连接,并将通信过程中的很多隐藏的信息都录制出来(如session、cookie)。LoadRunner提供了web_concurrent_start()和web_concurrent_end()函数模拟URL-basedscript的工作方式。  

下面以URL-basedscript方式录制一个登录的功能,录制后的代码如下:

web_url("WebTours",  

"URL=http://127.0.0.1:1080/WebTours/",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=",  

"Snapshot=t1.inf",  

"Mode=HTTP",  

LAST);  

web_concurrent_start(NULL);  

web_url("header.html",  

"URL=http://127.0.0.1:1080/WebTours/header.html",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=http://127.0.0.1:1080/WebTours/",  

"Snapshot=t2.inf",  

"Mode=HTTP",  

LAST);  

web_url("welcome.pl",  

"URL=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=http://127.0.0.1:1080/WebTours/",  

"Snapshot=t4.inf",  

"Mode=HTTP",  

LAST);  

web_concurrent_end(NULL);  

web_concurrent_start(NULL);  

web_url("hp_logo.png",  

"URL=http://127.0.0.1:1080/WebTours/images/hp_logo.png",  

"Resource=1",  

"RecContentType=image/png",  

"Referer=http://127.0.0.1:1080/WebTours/header.html",  

"Snapshot=t3.inf",  

LAST);  

web_url("webtours.png",  

"URL=http://127.0.0.1:1080/WebTours/images/webtours.png",  

"Resource=1",  

"RecContentType=image/png",  

"Referer=http://127.0.0.1:1080/WebTours/header.html",  

"Snapshot=t5.inf",  

LAST);  

web_concurrent_end(NULL);  

web_concurrent_start(NULL);  

web_url("home.html",  

"URL=http://127.0.0.1:1080/WebTours/home.html",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",  

"Snapshot=t6.inf",  

"Mode=HTTP",  

LAST);  

web_url("nav.pl",  

"URL=http://127.0.0.1:1080/WebTours/nav.pl?in=home",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",  

"Snapshot=t7.inf",  

"Mode=HTTP",  

LAST);  

web_concurrent_end(NULL);  

web_url("mer_login.gif",  

"URL=http://127.0.0.1:1080/WebTours/images/mer_login.gif",  

"Resource=1",  

"RecContentType=image/gif",  

"Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",  

"Snapshot=t8.inf",  

LAST);  

web_submit_data("login.pl",  

"Action=http://127.0.0.1:1080/WebTours/login.pl",  

"Method=POST",  

"RecContentType=text/html",  

"Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",  

"Snapshot=t9.inf",  

"Mode=HTTP",  

ITEMDATA,  

"Name=userSession","Value=108749.254191981ffQDHiQpHzcfDDfzcpHDifHf",ENDITEM,  

"Name=username","Value=test1",ENDITEM,  

"Name=password","Value=1",ENDITEM,  

"Name=JSFormSubmit","Value=off",ENDITEM,  

"Name=login.x","Value=63",ENDITEM,  

"Name=login.y","Value=9",ENDITEM,  

LAST);  

web_concurrent_start(NULL);  

web_url("nav.pl_2",  

"URL=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=http://127.0.0.1:1080/WebTours/login.pl",  

"Snapshot=t10.inf",  

"Mode=HTTP",  

LAST);  

web_url("login.pl_2",  

"URL=http://127.0.0.1:1080/WebTours/login.pl?intro=true",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=http://127.0.0.1:1080/WebTours/login.pl",  

"Snapshot=t12.inf",  

"Mode=HTTP",  

LAST);  

web_concurrent_end(NULL);  

web_concurrent_start(NULL);  

web_url("flights.gif",  

"URL=http://127.0.0.1:1080/WebTours/images/flights.gif",  

"Resource=1",  

"RecContentType=image/gif",  

"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",  

"Snapshot=t11.inf",  

LAST);  

web_url("itinerary.gif",  

"URL=http://127.0.0.1:1080/WebTours/images/itinerary.gif",  

"Resource=1",  

"RecContentType=image/gif",  

"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",  

"Snapshot=t13.inf",  

LAST);  

web_url("signoff.gif",  

"URL=http://127.0.0.1:1080/WebTours/images/signoff.gif",  

"Resource=1",  

"RecContentType=image/gif",  

"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",  

"Snapshot=t14.inf",  

LAST);  

web_url("in_home.gif",  

"URL=http://127.0.0.1:1080/WebTours/images/in_home.gif",  

"Resource=1",  

"RecContentType=image/gif",  

"Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",  

"Snapshot=t15.inf",  

LAST);  

web_concurrent_end(NULL);  

return0;

选择URL-basedscript选择,单击【URLAdvanced…】,弹出【AdvancedURL】对话框。关于URL的高级设置有两种方式:“CreateconcurrentgroupsforresourcestheirsourceHTMLpage”和“Useweb_custom_requestonly”。  

CreateconcurrentgroupsforresourcestheirsourceHTMLpage:将捕获所有HTML页面的资源,并将其保存在并发组中(并发组使用web_concurrent_start和web_concurrent_endstatements两个函数标识),如果不选中该选项时,HTML页面资源将会分成独立的、单独的web_url步骤,但并不放入并行组中。  

如以下代码: 

web_concurrent_start(NULL);  

...  

web_url("ClickHereForAdditionalRestrictions",  

"URL=http://www.hplab.com/restrictions.html",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=http://www.hplab.com/home?...  

"Snapshot=t4.inf",  

"Mode=HTTP",  

LAST);  

web_url("buttonhelp.gif",  

"URL=http://www.hplab.com/home?com/rstr?BV_EngineID...,  

"Resource=0",  

"RecContentType=text/html",  

"Referer=http://www.hplab.com/home?...  

"Snapshot=t5.inf",  

"Mode=HTTP",  

LAST);  

...  

web_concurrent_end(NULL);  

Useweb_custom_requestonly:如果录制的是非浏览器的应用程序,可以设置VuGen自定义HTTP请求,在LoadRunner中使用web_custom_reques函数来实现,不管内容如何。  

如以下代码:

web_custom_request("www.hplab.com",  

"URL=http://www.hplab.com/",  

"Method=GET",  

"Resource=0",  

"RecContentType=text/html",  

"Referer=",  

"Snapshot=t1.inf",  

"Mode=HTTP",  

LAST); 

选择HTML-basedscript还是URL-basedscript,应该根据实际需要进行,下面是一些常见的参考原则:  

1.基于浏览器的应用程序推荐使用HTML-basedscript。  

2.不是基于浏览器的应用程序推荐使用URL-basedscript。  

3.如果基于浏览器的应用程序中包含了JavaScript,并且该脚本向服务器发送了请求,比如DataGrid的分页按钮等,推荐使用URL-basedscript。  

4.基于浏览器的应用程序中使用了HTTPS安全协议,建议使用URL-basedscript。如果使用HTML-basedscript模式录制后不能成功回放,可以考虑改用URL-basedscript模式来录制。因为这种情况多是由上面所列举的原因所引起的。

Advanced选项卡

Advanced选项是设置脚本回放的高级选项,如图所示。

 

 

Savesnapshotresourceslocally:表示运行结果中保存一个快照。  

AddcommentstoscriptforHTTPerrorswhilerecording表示出现错误时会自动添加注释。  

点击Headers…按钮,会弹出HTTPHeaders配置对话框,如图所示。在该对话框中可以选择需要录制的Headers,以便服务器能够正确处理编辑信息。需要注意的是Accept-Language选项,像Websphere这类服务器会根据HTTP请求中的Header来确定编码。

 

 

Correlation选项卡

Correlation选项卡用来对脚本中的关联属性进行设置,如图3-19所示。LoadRunner包括两种规则:一是内建规则;二是:自定义的规则;LoadRunner会默认自带一些内建规格。在录制时选中需要的关联规则,录制脚本过程中LoadRunner会自动匹配需要关联的规格,并生成关联函数。如果当前的这些关联规则无法满足录制的需求,那么可以点击【NewApplication】按钮来新建一个关联,再点击【NewRule】按钮为该关联新建一个规则。

 

posted @ 2020-08-19 11:09  川石信息  阅读(341)  评论(0编辑  收藏  举报