第一篇:LoadRunner检查点使用小结
LR中检查点有两种:图片和文字。常用检查点函数如下:
1)web_find()函数用于从 HTML 页中搜索指定的文本字符串;
2)web_reg_find()函数注册一个请求,以在下一个操作函数(如 web_url)检索到的HTML网页上搜索指定的文本字符串;
3)web_image_check()函数用于从HTML页面中查找指定的图片;
4)web_global_verfication()属于注册函数,注册一个在web页面中搜索文本字符串的请求,与web_reg_find只在下一个Action函数中执行搜索不同的是它在之后所有的Action类函数中执行搜索指定的文本字符串; 下面分别介绍以上函数的用法:
1、web_find()函数参数举例:
web_find(“web_find”,“RighOf=a”,“LeftOf=b”,“What=name”,LAST);参数解释:“web_find”定义该查找函数的名称;“LeftOf”和“RighOf=”用来定义查找字符的左右边界;“What=”定义查找内容;
例如上述参数举例中的意思就是在页面中查找左边界为b,右边界为a,内容为name的信息;
使用该函数注意事项:该函数是在查找页面中的内容,所以要放在要查找的内容的后面;该函数只能在基于HTML模式录制的脚本中进行查找
注意事项:使用该函数时,要在Vuser->Run-Tme Settings中更改下设置
勾选Enable Image and text check
系统默认是不勾选该选项的。
2、web_reg_find()函数参数举例: web_reg_find(“Search=Body”,“SaveCount=ddd”,“Test=aaa”,LAST);参数解释: Search用来定义查找范围,SaveCount定义查找计数变量名称,该参数可以记录在缓存中查找内容出现的次数,可以使用该值,来判断要查找的内容是否被找到;
例如上述参数举例中的意思就是Body中查找内容为aaa的信息,并将出现次数记录在变量ddd中;
【代码一:web_reg_find(“Text=Payment Details”,LAST);代码思路:1.“Payment Details” 为你要检查的文本;
2.脚本执行到此处,若在页面上找到了这几个字符串,那脚本继续执行下去;若没有找到,脚本将在此报错并且结束。】
【代码二:web_reg_find(“Text=Payment Details”, “SaveCount=para_count”, LAST);//check 的函数
web_submit_form(“reservations.pl_2”, //要check的页面的录制时的代码 “Snapshot=t22.inf”, ITEMDATA, “Name=outboundFlight”, “Value=003;0;06/23/2007”, ENDITEM, “Name=reserveFlights.x”, “Value=61”, ENDITEM, “Name=reserveFlights.y”, “Value=2”, ENDITEM, LAST);if(atoi(lr_eval_string(“{para_count}”))>0)//验证是否找到了页面上的要检查的字符串
lr_output_message(“we find the string!”);else lr_output_message(“sorry,don't find the string!”);代码思路:1.“Payment Details” 为你要检查的文本;
2.脚本执行到此处,不管页面上是否存在你要检查的字符串,脚本都不会报错,而是执行下去。3.此段代码将找到的你要检查的字符串的个数,存为一个参数。然后在页面代码的后面,通过检查这个参数的值是否大于0,来判断是否找到了你所要检查的字符串。】 【代码三:
A.web_reg_find(“Text=Payment Detdils”, “Fail=NotFound”,LAST);或 B.web_reg_find(“Text=Payment Detdils”, “Fail=Found”,LAST);代码思路:
1.“Payment Details” 为你要检查的文本;
2.若是A代码:脚本执行到此处,若没有找到check的字符串,脚本将FAIL,并且停止执行下去。反之,则一直执行下去。
3.若是B代码:脚本执行到此处,若找到check的字符串,脚本将FAIL,并且停止执行下去。反之,则一直执行下去】
使用该函数注意事项:该函数是在缓存中查找相应的内容,所以要放在查找内容之前;通常情况下写在如下六个函数之前:Web_castom_request();web_image();web_link();web_submit_data();web_submit_form();web_url(); 使用技巧:在该函数的参数中有个“SaveCount”,该参数可以记录在缓存中查找内容出现的次数,我们可以使用该值,来判断要查找的内容是否被找到,下面举个例子来说明:(引用LR的帮助中的例子)// Run the Web Tours sample web_url(“MercuryWebTours”, “URL=http://localhost/MercuryWebTours/”, “Resource=0”, “RecContentType=text/html”, “Referer=”, “Snapshot=t1.inf”, “Mode=HTML”, LAST);// Set up check for successful login by looking for “Welcome” web_reg_find(“Text=Welcome”, “SaveCount=Welcome_Count”, LAST);// Now log in web_submit_form(“login.pl”, “Snapshot=t2.inf”, ITEMDATA, “Name=username”, “Value=jojo”, ENDITEM, Name=password“, ”Value=bean“, ENDITEM, ”Name=login.x“, ”Value=35“, ENDITEM, ”Name=login.y“, ”Value=14“, ENDITEM, LAST);// Check result if(atoi(lr_eval_string(”{Welcome_Count}“))> 0){ //判断如果Welcome字符串出现次数大于0 lr_output_message(”Log on successful.“);}//在日志中输出Log on successful else{ //如果出现次数小于等于
lr_error_message(”Log on failed“);//在日志中输出Log on failed return(0);} 我觉得这个方法非常有用,我们可以举一反三,应用到我们实际的项目 注:在录制过程中添加的检查点,用到的函数是web_reg_find(),且参数只有“Text=”
3、web_image_check()函数参数说明: web_image_check(”web_image_check“,”Alt=“,”Src=“,LAST);参数解释:“Alt”和“Src”的值直接取该图片在网页源代码中相应参数的值; 注意事项:使用该函数时,要在Vuser->Run-Tme Settings中勾选Enable Image and text check,具体操作请看web_find()中的注意事项。经过测试,该函数用到查找内容前面或后面,都不影响查找结果。举例说明(脚本)
该脚本记录的是登陆系统后退出的操作,在脚本中用到atoi()函数和lr_eval_string(”{SaveCount定义的变量}”)两个函数结合使用,判断查找内容出现的次数是否大于0,若大于0,则输入登录成功的信息。vuser_init(){ web_url(”xjcost“, ”URL=http://gczj-server8:9205/xjcost/“, ”Resource=0“, ”RecContentType=text/html“, ”Referer=“, ”Snapshot=t1.inf“, ”Mode=HTML“, EXTRARES, ”Url=jsp/images/index/index.swf“, ENDITEM, ”Url=jsp/images/index/xxfb2.gif“, ENDITEM, ”Url=jsp/images/index/ywpt2.gif“, ENDITEM, LAST);web_url(”userAction.struts“, ”URL=http://gczj-server8:9205/xjcost/userAction.struts?actionType=reLogin“, ”Resource=0“, ”RecContentType=text/html“, ”Referer=“, ”Snapshot=t2.inf“, ”Mode=HTML“, LAST);return 0;} Action(){ lr_start_transaction(”Log_on“);lr_rendezvous(”Log_on“);web_add_cookie(”userAccount=admin;DOMAIN=gczj-server8“);web_reg_find(”Text=欢迎您“, ”SaveCount=欢迎您_Count“, LAST);web_image_check(”web_image_check“, ”Src=/xjcost/jsp/images/index1/edit_01.gif“, LAST);web_submit_data(”userLogin.struts“, ”Action=http://gczj-server8:9205/xjcost/userLogin.struts?actionType=userLogin“, ”Method=POST“, ”RecContentType=text/html“, ”Referer=http://gczj-server8:9205/xjcost/userAction.struts?actionType=reLogin“, ”Snapshot=t3.inf“, ”Mode=HTML“, ITEMDATA, ”Name=userAccount“, ”Value=admin“, ENDITEM, ”Name=pwd“, ”Value=1111“, ENDITEM, EXTRARES, ”Url=jsp/images/index1/edit_01a.gif“, ”Referer=http://gczj-server8:9205/xjcost/userLogin.struts?actionType=userLogin“, ENDITEM, LAST);web_find(”web_find“, ”What=欢迎您“, LAST);lr_end_transaction(”Log_on“,LR_AUTO);//检查是否登录成功
//如果“欢迎您”这个字符出现次数大于0,输出“Log on successfully!”
if(atoi(lr_eval_string(”{欢迎您_Count}“))>0)lr_output_message(”Log on successfully!“);else lr_error_message(”Log on failed!“);return 0;return 0;} //atoi()函数的作用是将一个ASCII字符串转换为整型
//lr_eval_string()函数作用是取得参数值,将字符串变量中的参数值替换为当前的参数值并将这个字符串返回 vuser_end(){ lr_think_time(4);web_url(”userAction.struts_2“, ”URL=http://gczj-server8:9205/xjcost/userAction.struts?actionType=reLogin“, ”Resource=0“, ”RecContentType=text/html“, ”Referer=“, ”Snapshot=t4.inf“, ”Mode=HTML“, LAST);return 0;} Global.h:
#ifndef _GLOBALS_H #define _GLOBALS_H //------// Include Files #include ”lrun.h“ #include ”web_api.h“ #include ”lrw_custom_body.h“ //------// Global Variables #endif // _GLOBALS_H Replay Log常见信息说明
1、web_find()和web_image_check()函数的日志信息(这两个日志信息实际上是一样的,只是输出的函数名和参数不同)
1)信息1Action.c(22): Verification checks not enabled.web_image_check is skipped.See the 'Run-time settings/Preferences/Checks' [MsgId: MMSG-27197] Action.c(22): web_image_check was successful [MsgId: MMSG-26392] 出现该信息,说明没有勾选Enable Image and text check 2)信息2Action.c(22): ”web_image_check“ succeeded(1 occurrence(s)found.Alt=”“, Src=”/xjcost/jsp/images/index1/edit_01.gif“)[MsgId: MMSG-27192] Action.c(22): web_image_check was successful [MsgId: MMSG-26392] 出现该信息,说明检查点设置成功,且已经查找到信息
3)信息3Action.c(22): Error-27191: ”web_image_check“ failed(0 occurrence(s)found.Alt=”“, Src=”/xjcost/jsp/images/index1/edit_1.gif“)[MsgId: MERR-27191] Action.c(22): web_image_check highest severity level was ”ERROR“ [MsgId: MMSG-26391] 出现该信息,说明要查找的内容没有找到。这时依次尝试以下操作:(1)检查参数的信息是否写错;
(2)如果是web_find(),检查函数的位置是否在要查找内容的后面;(3)如果是web_image_check(),查看该图片的源代码,看其是否是这个页面上的图片,很可能是图片选择错误,即所选图片不属于该页面。
2、web_reg_find()函数的日志信息
1)信息1Action.c(15): Registering web_reg_find was successful [MsgId: MMSG-26390] 出现该信息,说明内容已查找到
2)信息2Action.c(27): Error-26366: ”Text=ABC“ not found for web_reg_find [MsgId: MERR-26366] Action.c(27): web_submit_data(”userLogin.struts“)highest severity level was ”ERROR", 18364 body bytes, 918 header bytes, 13 chunking overhead bytes [MsgId: MMSG-26387] 该信息在replay log页面是红色显示的,说明没有找到内容,出现此情况尝试以下两个操作:
(1)参数的信息是否正确;
(2)查看该函数是否在查找内容的前面。插入函数的方法:
1、手工写入,在需要插入函数的位置手工写入该函数;
2、光标停留在要插入函数的位置,在INSERT菜单中,选择new step,在列表中选择或查找要插入的函数,根据提示填写必要的参数;
3、在tree view模式下,在树状菜单中选中要插入函数的位置,右键,选择insert after或insert before,根据提示填写必要的参数; 总结:
1、这两个函数函数类型不同,WEB_FIND是普通函数,WEB_REG_FIND是注册函数;
2、WEB_FIND使用时必须开启内容检查选项,而WEB_REG_FIND则不没有此限制;
3、WEB_FIND只能用在基于HTML模式录制的脚本中,而WEB_REG_FIND没有此限制;
4、WEB_FIND是在返回的页面中进行内容查找,WEB_REG_FIND是在缓存中进行查找;
5、WEB_FIND在执行效率上不如WEB_REG_FIND;
第二篇:LoadRunner检查点使用小结
LoadRunner检查点使用小结
LR中检查点有两种:图片和文字。这两种检查点可用以下三个函数实现:web_find()、web_reg_find()和web_image_check()下面分别介绍三种函数的用法
1、web_find()函数
函数作用:在页面中查找相应的内容
参数举例:web_find(“web_find”,“RighOf=a”,“LeftOf=b”,“What=name”,LAST);参数解释:“web_find”定义该查找函数的名称;“LeftOf”和“RighOf=”用来定义查找字符的左右边界;“What=”定义查找内容。
例如上述参数举例中的意思就是在页面中查找左边界为b,右边界为a,内容为name的信息 函数用法:该函数是在查找页面中的内容,所以要放在要查找的内容的后面。注意事项:使用该函数时,要在Vuser->Run-Tme Settings中更改下设置
勾选Enable Image and text check
系统默认是不勾选该选项的。
2、web_reg_find()函数
函数作用:在缓存中查找相应的内容
参数举例:web_reg_find(“Search=Body”,“SaveCount=ddd”,“Test=aaa”,LAST);参数解释: Search用来定义查找范围,SaveCount定义查找计数变量名称,该参数可以记录在缓存中查找内容出现的次数,可以使用该值,来判断要查找的内容是否被找到
例如上述参数举例中的意思就是Body中查找内容为aaa的信息,并将出现次数记录在变量ddd中。函数用法:该函数是在缓存中查找相应的内容,所以要放在查找内容之前。
注:在录制过程中添加的检查点,用到的函数是web_reg_find(),且参数只有“Text=”
3、web_image_check()函数
函数作用:在页面中查找一个具体的图片。
参数说明:web_image_check(“web_image_check”,“Alt=”,“Src=”,LAST);;参数解释:“Alt”和“Src”的值直接取该图片在网页源代码中相应参数的值。函数用法:该函数是在缓存中查找相应的内容,所以要放在查找内容之前。
注意事项:使用该函数时,要在Vuser->Run-Tme Settings中勾选Enable Image and text check,具体操作请看web_find()中的注意事项。
经过测试,该函数用到查找内容前面或后面,都不影响查找结果。举例说明(脚本)
该脚本记录的是登陆系统后退出的操作,在脚本中用到atoi()函数和lr_eval_string(”{SaveCount定义的变量}”)两个函数结合使用,判断查找内容出现的次数是否大于0,若大于0,则输入登录成功的信息。
vuser_init()
{
web_url(“xjcost”,“URL=http://gczj-server8:9205/xjcost/”,“Resource=0”,“RecContentType=text/html”,“Referer=”, “Snapshot=t1.inf”, “Mode=HTML”, EXTRARES,“Url=jsp/images/index/index.swf”, ENDITEM, “Url=jsp/images/index/xxfb2.gif”, ENDITEM, “Url=jsp/images/index/ywpt2.gif”, ENDITEM,LAST);
web_url(“userAction.struts”, “URL=http://gczj-server8:9205/xjcost/userAction.struts?actionType=reLogin”,“Resource=0”,“RecContentType=text/html”,“Referer=”, “Snapshot=t2.inf”, “Mode=HTML”,LAST);return 0;
} Action()
{
lr_start_transaction(“Log_on”);lr_rendezvous(“Log_on”);web_add_cookie(“userAccount=admin;DOMAIN=gczj-server8”);
web_reg_find(“Text=欢迎您”, “SaveCount=欢迎您_Count”,LAST);
web_image_check(“web_image_check”, “Src=/xjcost/jsp/images/index1/edit_01.gif”,LAST);
web_submit_data(“userLogin.struts”, “Action=http://gczj-server8:9205/xjcost/userLogin.struts?actionType=userLogin”,“Method=POST”, “RecContentType=text/html”, “Referer=http://gczj-server8:9205/xjcost/userAction.struts?actionType=reLogin”,“Snapshot=t3.inf”, “Mode=HTML”, ITEMDATA, “Name=userAccount”, “Value=admin”, ENDITEM,“Name=pwd”, “Value=1111”, ENDITEM,EXTRARES,“Url=jsp/images/index1/edit_01a.gif”, “Referer=http://gczj-server8:9205/xjcost/userLogin.struts?actionType=userLogin”, ENDITEM,LAST);
web_find(“web_find”, “What=欢迎您”,LAST);
lr_end_transaction(“Log_on”,LR_AUTO);
//检查是否登录成功
//如果“欢迎您”这个字符出现次数大于0,输出“Log on successfully!”
if(atoi(lr_eval_string(“{欢迎您_Count}”))>0)lr_output_message(“Log on successfully!”);
else
lr_error_message(“Log on failed!”);
return 0;return 0;
} //atoi()函数的作用是将一个ASCII字符串转换为整型
//lr_eval_string()函数作用是取得参数值,将字符串变量中的参数值替换为当前的参数值并将这个字符串返
回 vuser_end()
{
lr_think_time(4);
web_url(“userAction.struts_2”, “URL=http://gczj-server8:9205/xjcost/userAction.struts?actionType=reLogin”,“Resource=0”,“RecContentType=text/html”,“Referer=”, “Snapshot=t4.inf”, “Mode=HTML”,LAST);return 0;
} Global.h: #ifndef _GLOBALS_H #define _GLOBALS_H //------
// Include Files #include “lrun.h” #include “web_api.h” #include “lrw_custom_body.h” //------
// Global Variables #endif // _GLOBALS_H Replay Log常见信息说明
1、web_find()和web_image_check()函数的日志信息(这两个日志信息是上一样的,只是输出的函数名和参数不同)
1)信息1Action.c(22): Verification checks not enabled.web_image_check is skipped.See the 'Run-time settings/Preferences/Checks' [MsgId: MMSG-27197] Action.c(22): web_image_check was successful [MsgId: MMSG-26392] 出现该信息,说明没有勾选Enable Image and text check 2)信息2Action.c(22): “web_image_check” succeeded(1 occurrence(s)found.Alt=“", Src=”/xjcost/jsp/images/index1/edit_01.gif“)[MsgId: MMSG-27192] Action.c(22): web_image_check was successful [MsgId: MMSG-26392] 出现该信息,说明检查点设置成功,且已经查找到信息
3)信息3Action.c(22): Error-27191: ”web_image_check“ failed(0 occurrence(s)found.Alt=”“, Src=”/xjcost/jsp/images/index1/edit_1.gif“)[MsgId: MERR-27191] Action.c(22): web_image_check highest severity level was ”ERROR“ [MsgId: MMSG-26391] 出现该信息,说明要查找的内容没有找到。这时依次尝试以下操作:(1)检查参数的信息是否写错;
(2)如果是web_find(),检查函数的位置是否在要查找内容的后面;
(3)如果是web_image_check(),查看该图片的源代码,看其是否是这个页面上的图片,很可能是图片选择错误,即所选图片不属于该页面。
2、web_reg_find()函数的日志信息
1)信息1Action.c(15): Registering web_reg_find was successful [MsgId: MMSG-26390] 出现该信息,说明内容已查找到
2)信息2Action.c(27): Error-26366: ”Text=ABC“ not found for web_reg_find [MsgId: MERR-26366] Action.c(27): web_submit_data(”userLogin.struts“)highest severity level was ”ERROR", 18364 body bytes, 918 header bytes, 13 chunking overhead bytes [MsgId: MMSG-26387] 该信息在replay log页面是红色显示的,说明没有找到内容,出现此情况尝试以下两个操作:(1)参数的信息是否正确;
(2)查看该函数是否在查找内容的前面。
第三篇:loadrunner使用cookie模拟
loadrunner使用cookie模拟
自己的工作总结,大家讨论讨论
1为什么要使用cookie模拟
从日常项目测试过程中的问题说起。
比如要进行论坛中的文件下载功能的测试。我们都知道只有登录用户才能进行下载操作,这样我们的测试过程可能就变成了先登录系统,然后再进行下载操作。在使用loadrunner设计脚本时就要先在初始化部分写登录脚本,然后再action中写下载操作,当单个用户运行时我们可能看不到什么问题。当用户并发量较多时,问题马上暴露出来了。大部分用户可能很长时间也没有下载成功,大量的初始化登录操作已经给系统造成了很大的压力,而在日常访问中,这种大量短时间登录的压力是不容易出现的。这样的测试结果可能无法达到我们的测试目标。的确,不能处理较大的登录吞吐可能已经是系统的瓶颈了,我们可以通过这种全流程的测试方式发现登录的问题。但是后续的测试我们可能就无法进行下去了。当项目组解决了登录的吞吐问题时,可能项目工期已经十分紧张了,再进行重要的下载功能测试可能已经太晚了。
这种情况在测试过程中经常会出现,我们要如何绕过登录尽早的进行后续的下载操作呢?如果网站使用了cookie的机制,则我们可以尝试使用下面的方法。
2怎么使用loadrunner模拟
Loadrunner的web函数中提供了几个关于cookie的函数。
web_remove_cookie()
web_add_cookie()
web_cleanup_cookies();
web_reg_add_cookie();
这里我们为了模拟cookie绕过登录使用web_add_cookie();
首先获取网站留在客户端上的cookie都存储了什么。通常主要内容包括名字,值,过期时间,作用域和路径,分为会话cookie和文件cookie。会话cookie存储在内存里,关闭浏览器后就没有了,这种很难模拟。文件cookie是将cookie信息写到硬盘上,关闭浏览器再次打开后仍可以使用。我们要模拟的就是这种存储在硬盘文件里的cookie。我们观察cookie文件的内容,如果使用ie的话,在“C:Documents and Settings用户名Local SettingsTemporary Internet Files”中的用户名@域名的文件里,cookie存储都是加密的,所以我们直接看并看不出什么特别的东西,也搞不清楚具体是什么。这时我们借助IE webdeveloper 工具获取cookie值如下所示:
cdb_cookietime=2592000;cdb_smile=1D1;cdb_sid=71WKOd;cdb_auth=TzsVl16XRFahjqkfuWyoF5OzI%2BrekHgiy0YXJd8m1y9vq6aV4bg3GGMsa9s;cdb_visitedfid=20;cdb_onlineusernum=28
获得了cookie信息后,我们进行编辑loadrunner脚本。将cookie每个分号分行,使用UltraEdit进行列模式操作,在每句后面加上域名。(域名在webdeveloper的Attributes下也可以找到domain对应值),修改完成后如下。
web_add_cookie(“cdb_cookietime=2592000;domain=172.16.1.3”);
web_add_cookie(“cdb_smile=1D1;domain=172.16.1.3”);
web_add_cookie(“cdb_sid=71WKOd;domain=172.16.1.3”);
web_add_cookie(“cdb_auth=TzsVl16XRFahjqkfuWyoF5OzI%2BrekHgiy0YXJd8m1y9vq6aV4b
g3GGMsa9s;domain=172.16.1.3”);
web_add_cookie(“cdb_visitedfid=20;domain=172.16.1.3”);
web_add_cookie(“cdb_onlineusernum=28;domain=172.16.1.3”);
把这些值放在要访问的url的web函数之前,你就可以绕过登录进行后续操作了。如:
Action()
{
web_add_cookie(“cdb_cookietime=2592000;DOMAIN=172.16.1.3”);
web_add_cookie(“cdb_smile=1D1;DOMAIN=172.16.1.3”);
web_add_cookie(“cdb_oldtopics=D280D39523D39418D;DOMAIN=172.16.1.3”);
web_add_cookie(“cdb_sid=eSuWgw;DOMAIN=172.16.1.3”);
web_add_cookie(“cdb_auth=TzsVl16XRFahjqkfuWyoF5OzI%2BrekHgiy0YXJd8m1y9vq6aV4bg3GGMsa9s;DOMAIN=172.16.1.3”);
web_add_cookie(“cdb_visitedfid=20;DOMAIN=172.16.1.3”);
web_url(“cookies”,“URL=http://172.16.1.3:8080/bbs/index.php”,“referer=http://172.16.1.3/newiweb/index/dealIndex.do?action=Index”,“Mode=HTML”,“RecContentType=text/html”,LAST);
return 0;
}
最后注明一下:loadrunner的web录制功能是自动的增加cookie的,只要在cookie不过期的情况下,我们不需要手工的增加cookie,当出现录制不上或录制的值发生变化时可以手工进行添加。
在loadrunner场景设计使用其他负载机器时,同样可以使用你本机的这个cookie值进行,不会因为客户端机器发生变化而产生影响。
第四篇:LoadRunner测试总结
性能测试(并发负载压力)测试分析-简要篇
在论坛混了多日,发现越来越多的性能测试工程师基本上都能够掌握利用测试工具来作负载压力测试,但多数人对怎样去分析工具收集到的测试结果感到无从下手,下面我就把个人工作中的体会和收集到的有关资料整理出来,希望能对大家分析测试结果有所帮助。
分析原则:
• 具体问题具体分析(这是由于不同的应用系统,不同的测试目的,不同的性能关注点)• 查找瓶颈时按以下顺序,由易到难。
服务器硬件瓶颈-〉网络瓶颈(对局域网,可以不考虑)-〉服务器操作系统瓶颈(参数配置)-〉中间件瓶颈(参数配置,数据库,web服务器等)-〉应用瓶颈(SQL语句、数据库设计、业务逻辑、算法等)注:以上过程并不是每个分析中都需要的,要根据测试目的和要求来确定分析的深度。对一些要求低的,我们分析到应用系统在将来大的负载压力(并发用户数、数据量)下,系统的硬件瓶颈在哪儿就够了。• 分段排除法 很有效
分析的信息来源:
•1 根据场景运行过程中的错误提示信息
•2 根据测试结果收集到的监控指标数据
一.错误提示分析
分析实例:•Error: Failed to connect to server “10.10.10.30:8080”: [10060] Connection
•Error: timed out Error: Server “10.10.10.30” has shut down the connection prematurely
分析:
•A、应用服务死掉。
(小用户时:程序上的问题。程序上处理数据库的问题)
•B、应用服务没有死
(应用服务参数设置问题)
例:在许多客户端连接Weblogic应用服务器被拒绝,而在服务器端没有错误显示,则有可能是Weblogic中的server元素的AcceptBacklog属性值设得过低。如果连接时收到connection refused消息,说明应提高该值,每次增加25%
•C、数据库的连接
(1、在应用服务的性能参数可能太小了
2、数据库启动的最大连接数(跟硬件的内存有关))
2Error: Page download timeout(120 seconds)has expired
分析:可能是以下原因造成•A、应用服务参数设置太大导致服务器的瓶颈
•B、页面中图片太多
•C、在程序处理表的时候检查字段太大多
二.监控指标数据分析
1.最大并发用户数:
应用系统在当前环境(硬件环境、网络环境、软件环境(参数配置))下能承受的最大并发用户数。在方案运行中,如果出现了大于3个用户的业务操作失败,或出现了服务器shutdown的情况,则说明在当前环境下,系统承受不了当前并发用户的负载压力,那么最大并发用户数就是前一个没有出现这种现象的并发用户数。
如果测得的最大并发用户数到达了性能要求,且各服务器资源情况良好,业务操作响应时间也达到了用户要求,那么OK。否则,再根据各服务器的资源情况和业务操作响应时间进一步分析原因所在。
2.业务操作响应时间:
• 分析方案运行情况应从平均事务响应时间图和事务性能摘要图开始。使用“事务性能摘要”图,可以确定在方案执行期间响应时间过长的事务。
• 细分事务并分析每个页面组件的性能。查看过长的事务响应时间是由哪些页面组件引起的?问题是否与网络或服务器有关?
• 如果服务器耗时过长,请使用相应的服务器图确定有问题的服务器度量并查明服务器性能下降的原因。如果网络耗时过长,请使用“网络监视器”图确定导致性能瓶颈的网络问题
3.服务器资源监控指标:
内存:UNIX资源监控中指标内存页交换速率(Paging rate),如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。也可能是内存访问命中率低。Windows资源监控中,如果ProcessPrivate Bytes计数器和ProcessWorking Set计数器的值在长时间内持续升高,同时MemoryAvailable bytes计数器的值持续降低,则很可能存在内存泄漏。
内存资源成为系统性能的瓶颈的征兆:
很高的换页率(high pageout rate);
进程进入不活动状态;
交换区所有磁盘的活动次数可高;
可高的全局系统CPU利用率;
内存不够出错(out of memory errors)
处理器:UNIX资源监控(Windows操作系统同理)中指标CPU占用率(CPU utilization),如果该值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。如果服务器专用于SQL Server,可接受的最大上限是80-85%
合理使用的范围在60%至70%。Windows资源监控中,如果SystemProcessor Queue Length大于2,而处理器利用率(Processor Time)一直很低,则存在着处理器阻塞。
CPU资源成为系统性能的瓶颈的征兆:
很慢的响应时间(slow response time)
CPU空闲时间为零(zero percent idle CPU)
过高的用户占用CPU时间(high percent user CPU)
过高的系统占用CPU时间(high percent system CPU)
长时间的有很长的运行进程队列(large run queue size sustained over time)
磁盘I/O:UNIX资源监控(Windows操作系统同理)中指标磁盘交换率(Disk rate),如果该参数值一直很高,表明I/O有问题。可考虑更换更快的硬盘系统。Windows资源监控中,如果 Disk Time和Avg.Disk Queue Length的值很高,而Page Reads/sec页面读取操作速率很低,则可能存在磁盘瓶径。
I/O资源成为系统性能的瓶颈的征兆 :
过高的磁盘利用率(high disk utilization)
太长的磁盘等待队列(large disk queue length)
等待磁盘I/O的时间所占的百分率太高(large percentage of time waiting for disk I/O)太高的物理I/O速率:large physical I/O rate(not sufficient in itself)
过低的缓存命中率(low buffer cache hit ratio(not sufficient in itself))
太长的运行进程队列,但CPU却空闲(large run queue with idle CPU)
4.数据库服务器:
SQL Server数据库:SQLServer资源监控中指标缓存点击率(Cache Hit Ratio),该值越高越好。如果持续低于80%,应考虑增加内存。如果Full Scans/sec(全表扫描/秒)计数器显示的值比1或2高,则应分析你的查询以确定是否确实需要全表扫描,以及SQL查询是否可以被优化。Number of Deadlocks/sec(死锁的数量/秒):死锁对应用程序的可伸缩性非常有害,并且会导致恶劣的用户体验。该计数器的值必须为0。Lock Requests/sec(锁请求/秒),通过优化查询来减少读取次数,可以减少该计数器的值。
Oracle数据库:如果自由内存接近于0而且库快存或数据字典快存的命中率小于0.90,那么需要增加
SHARED_POOL_SIZE的大小。
快存(共享SQL区)和数据字典快存的命中率:
select(sum(pins-reloads))/sum(pins)from v$librarycache;
select(sum(gets-getmisses))/sum(gets)from v$rowcache;
自由内存:select * from v$sgastat where name=’free memory’;如果数据的缓存命中率小于0.90,那么需要加大DB_BLOCK_BUFFERS参数的值(单位:块)。缓冲区高速缓存命中率:
select name,value from v$sysstat where name in('db block gets’,'consistent gets','physical reads');
Hit Ratio = 1-(physical reads /(db block gets + consistent gets))如果日志缓冲区申请的值较大,则应加大LOG_BUFFER参数的值。
日志缓冲区的申请情况 :
select name,value from v$sysstat where name = 'redo log space requests';如果内存排序命中率小于0.95,则应加大SORT_AREA_SIZE以避免磁盘排序。
内存排序命中率 :
select round((100*b.value)/decode((a.value+b.value), 0, 1,(a.value+b.value)), 2)from v$sysstat a, v$sysstat b where a.name='sorts(disk)' and b.name='sorts(memory)'
注:上述SQL Server和Oracle数据库分析,只是一些简单、基本的分析,特别是Oracle数据库的分析和优化,是一门专门的技术,进一步的分析可查相关资料。
说明:
以上只是个人的体会和部分资料的整理,并不代表专家之言。算抛砖引玉,有不同看法和更深入的分析的,希望大家勇要发言,以推动我们国内的性能测试工作。
第五篇:LoadRunner学习总结
LoadRunner学习小结
今年十月份我到北京跟张坤学习性能测试知识,共花了三个星期学习LoadRunner。以下是我的学习小结。
一. 什么是LoadRunner LoadRunner是一种预测系统行为和性能的工业标准级负载测试工具。通过以模拟多个用户实施并发负载测试及实时性能检测的方式来确认和查找问题,能对整个企业架构进行测试。
二. LoadRunner的优点
1.轻松创建虚拟用户:通过记录下业务流程转为测试脚本,在机器上产生多个用户访问,减少负载测试需要的硬件和人力资源。
2.创建真实的负载:可以通过Controller设定负载方案,如定义用户在什么时候访问系统以产生负载,所有用户同时执行一个动作来模拟峰值负载情况等。3.实时监测器:可以实时显示交易性能数据(如响应时间)和其他系统组件如数据库,网络等的实时性能。
4.分析结果以精确定位问题所在:LoadRunner能收集汇总所有测试数据,提供高级的分析和报告工具。
三. LoadRunner的安装与使用
1.安装过程详见上传的LoadRunner使用手册,在此不再详细介绍。2.具体使用:
点击File新建录制文件,也可以点击下面的NEW快捷键进行新建。使用File新建,会弹出协议选择窗口,选择新的单协议脚本(New Single Protocol Script)的Web(HTTP/HTML)项,确定即可(选择Web项是因为我们测试的是Web应用)。接着会弹出开始录制的设置项,需要写入录入系统的地址,点击确定后就会根据录入地址展现系统页面,开始录制脚本,出现小工具条:
第一个按钮为录制键 第二个为回放脚本键 第三个为停止录制键 第四个为暂停录制键 第五个为编译脚本键
第六个为创建新的Action键。LR的录制脚本分为三个部分,vuser_init、vuser_end和 Action。脚本循环执行时,只执行一次vuser_init和vuser_end,而多次循环Action部分。比如录制投保业务时,登陆系统部分放入vuser_init,退出登陆放到vuser_end,中间的投保操作放到Action中,则循环执行时就会登陆一次投保系统开始反复执行投保操作直到结束退出系统。
第七个为用来改变录制的options设置按钮
第八个和第九个为插入事务的起始点和结束点键,结合起来构成一个完整事物,用来衡量服务器的性能。比如录制脚本过程中,投保系统的查询投保单号操作,可以在输入完查询信息后点击查询按钮前插入事务的起始点,查询出数据后插入事务的结束点,这样在运行测试脚本时,Loadrunner在运行到该事务时,便会计算出这个查询操作所花时间,便于衡量服务器执行查询操作的性能。
第十个为插入集合点键,可用于衡量在加重负载的情况下服务器的性能。比如要验证系统是否能承受100人同时进行报案操作,便可在脚本录入过程中,点击报案确认键操作前插入集合点,这样当脚本运行到集合点时,Loadrunner会让100个虚拟用户同时点击报案确认按钮(如果有的用户还没运行到集合点,先到用户要等未到用户一起操作)进行报案,从而达到测试目的。
最后一个为设置验证点键,在创建事物后,设置一个验证点可以用来确认事物执行是否成功。比如进行查询事务操作时,LR只要检测到网页的响应,就认为事务pass,而不管显示页面内容是否正确。因此为了检查Web服务器返回的网页是否正确,可以插入Text/Image检查点,验证网页上是否存在指定的Text或Image。
设置验证点时,如果我们验证的文本内容是中文,有时会返回无法找到验证内容的报错信息,而页面显示又是正确的,出现问题的原因可能是因为LR对中文的支持部好,尽量选择验证信息为数字或字母;也可能是设置问题,可以尝试将Tools->Recording Options->HTTP Properties下的Advanced选项里设置支持UTF-8,再检查开发人员有没有设置支持中文。
录制结束后,先点击保存脚本,同时为脚本命名。然后编译脚本,看是否存在语法错误,编译成功后,即可回放,看录制脚本是否成功。
LoadRunner录制得到的脚本基本没有错误,不像robot会有录入数据的缺失,只是会录入一些非录入系统的网页信息,根据地址可以识别并删除掉。
四. LoadRunner脚本录制学习小结
1.LoadRunner录制脚本,主要是为了进行压力测试,所以跑流程时,跑了主要流程即可,也就是系统必须的信息录入就可以了。2.LoadRunner的脚本运行过程中,只能用于一次业务办理的数据需要做参数化,如车辆车架号,车牌,报案号等,以免出现重复投保或报案无法立案现象,不能继续进行下去。参数化步骤:
1)将需要做参数化的数据右键点击,选择Replace with a parameter,进行设置。2)在弹出编辑框里,设置易懂的参数名称,再点击Properties进行属性设置。3)点击Create Table 按钮,生成参数表格,再点击Edit with Notepad按钮,即可在记事本里添加新的参数,添加完后再次回车(不回车可能最后条数据读取不到)关闭,参数化操作完成。
4)使用Ctrl +H键可以找到替换同样的需要参数化的数据。
3.脚本跑流程过程中,因为业务运转,前面生成的投保单要接着进行提交核保业务,而每次生成的投保单号不一样,用于进行提交核保的单号也要与之前的保持一致,因此需要做关联处理,读取到生成的新投保单号给提交核保流程。关联步骤:
1).查找关联数据第一次出现的位置,判断该数据是由什么函数返回的。
2).在树形结构里点击返回该数据值的函数,看它的Server Response信息,用复制的关联数据进行查找它的返回语句,找到区分度明显的语句(不一定要是第一个返回语句),然后使用web_reg_save_param函数进行关联。
注:关联函数一定要写在第一个返回该数据值的函数前。
3).web_reg_save_param(const char *ParamName, , LAST);
函数的第一个参数是用来对关联数据进行定义的,取名最好可读性强;第二个参数是用来标识关联数据在返回语句里的具体位置的,写出该数据的左右边界,程序才能识别;LAST表示属性列的结束。比如办理理赔业务的流程号,在服务器的返回语句里是:
做关联为:
web_reg_save_param(“LogFlowID”,“LB=name=flowID type=”hidden“ value=”,“RB=>”,LAST);定义的参数名就叫LogFlowID,表示流程号,易于明白;左边界从name取就可以标识了,也可取长点或短点,只要能区分;右边界只有>,写上就好;最后写上LAST。
在定义的左右边界中,如果有双引号,在脚本中是需要转义的,因为双引号在C中是有意义的,这里只要表示语句信息,加上右斜杠。尖括号直写。
左右边界也需要用双引号括起来。定义好的参数写在程序中,需要在加上单尖括号:swfLogFlowID={LogFlowID} 五. 脚本执行过程中的报错处理
1.vuser_init.c(3051): Error-26377: No match found for the requested parameter “proposalNo”.Check whether the requested boundaries exist in the response data.Also, if the data you want to save exceeds 256 bytes, use web_set_max_html_param_len to increase the parameter size [MsgId: MERR-26377] 2.vuser_init.c(3051): web_submit_data(“UIPrPoEnInputNext.jsp”)highest severity level was “ERROR”, 4312 body bytes, 258 header bytes [MsgId: MMSG-26388]
两个错误一起出现,出错语句都是在关联函数下的提交数据函数位置,但是具体出错有可能是:
1).关联函数左右边界没写对,所有信息都要用字符输入,不能是中文或其他。
2).在关联函数确认写对的情况下,看提交数据函数中的业务设置,比如有可能是因为保单查询语句,设置的查询时间是过去的时间,新生成的投保单当然查不到,这样程序也会报这样的错。
3.loadrunner 执行理赔的立案处理,录制好脚本后,回放,报错:
脚本日志信息提示:
1.Action.c(400): Error-26366: “Text=立案信息提交成功” not found for web_reg_find [MsgId: MERR-26366] 2.Action.c(400): web_submit_data(“claimSave.do”)highest severity level was “ERROR”, 4424 body bytes, 258 header bytes [MsgId: MMSG-26388] 脚本执行过程停止在立案信息提交页面,错误原因:数据问题,可能是有的应该变化的信息没有变。
在该流程中,一个报案号只能做一次立案,而初始脚本没有设置参数、关联,使用保单号进行查询,错误被掩盖。在立案系统中,一个保单号可以重复报案,但是一个报案号只能一次立案,要跑通流程,需要先将这一保单再重复报案,得到新的报案号。
六. 性能测试的场景设置
脚本录制完毕后,接着准备测试场景。1.首先准备测试数据。比如车险投保,需要投保人和车架号信息来唯一标识一辆被保车,因此就需要将投保人和车架号做参数化处理,编辑文本框录入大量数据让脚本唯一读取:
1).录入投保人参数,车架号参数,过程同脚本录制的参数化处理
2).因为投保人和车架号一起生成一条投保数据,可设置车架号随投保人参数一起读取,设置步骤为:
投保人文件存放路径--File path
投保人参数数据读取方式
脚本按列名读取参数,每行数据读取一次,每次循环取一次新值。接着设置车架号参数信息:
车架号参数读取文件路径设为和投保人文件路径一样
脚本按列名读取参数,行号选择和读取的投保人数据同一行
这样得到所需的投保单生成参数数据
2.设置测试场景
点击Tools->Create Controller Scenarios,弹出场景类型选择框:
录入需要的虚拟用户数,选择生成结果存放路径和组名。确定后进入具体设置页面:
Quantity表示虚拟用户个数,group name为组名。
1).设置运行时间选项Run – time Settings
选择循环次数Run Logic->Iteration Count,设置循环10次,虚拟用户数为之前设置的5人,则预计一共可生成50张投保单。
设置思考时间,思考时间通常是录制脚本过程中,填写页面信息花费的时间,选择忽略项,节省跑脚本的时间。
设置网络连接时间,点击网络协议项Internet Protocol 的Options键,将弹出页面里的HTTP-request connect timeout和 HTTP-request receive timeout的数值改为1000。使得能在网络状况不太好的情况下向服务器发送接收数据。
2).设置Edit Schedule
选择虚拟用户加载方式:
可以一次加载所有用户,也可以按需要设置,一秒加载一个用户或其他。
选择结束方式:
当选择一秒加载一个用户时,结束设置为直到跑完所有脚本停止执行。如果选择选择一次加载所有用户可以选择运行多少时间后停止和不停止选项。
这些设置完成后,一次测试场景布置完成。可以进行基线检查或单点并发测试。
七. 性能测试步骤
一).除测试工具外性能测试必备的系统及业务知识
1、熟悉保险行业业务特点,有助于与开发和客户讨论需求,制定测试用例;
2、熟悉系统的实现特点,开发实现方式,有助于选择程序处理复杂、消耗系统资源的用例点;
3、熟悉数据结构,了解数据存储规则,对脚本调试、数据准备、测试执行和监视都有帮助;
4、熟悉系统所使用的数据库、操作系统、中间件的监视和性能问题查看,有助于测试监视和发现问题;
5、熟悉系统架构及系统集成方式,有助于分析及明确定位性能问题。
二)性能测试执行过程 1.基线检查
1).目的:验证环境是否可用;
验证脚本是否能在场景正常执行。
2).方法:1个人单独循环5次--没有其他人干扰,干净的环境
3).结果:一般一个事物的响应时间超过3秒就可能存在问题,要提报开发人
2.单点并发
1).目的:为了快速的发现问题,如多进程的锁机制,看是否相互间有影响。2).方法:一般是10人或20人执行10到15分钟,执行过程忽略思考时间。
忽略思考时间可以减少客户端时间,加快向服务器传送数据速度,很大程度上增大了服务器的压力,20个人单点并发的压力就相当于200人正常执行带给服务器的压力。
3).单点测试的数据可以用来进行混发测试,但是有可能单点测试的数据不足以进行混发,需要自己再准备足够的数据。
3.方案测试--混发测试
1).目的:模拟生产环境
2).方法:执行1小时左右,加上思考时间
八.资源监控及调优
性能测试执行过程中,需要监控系统各项资源,看是否能满足用户实际需要,如内存使用,SQL SERVER等,结合LR生成的分析报告,分析系统哪里可能存在问题,需要改进,进行调优,这也是我之后要接着进行学习的地方。
1.学习使用weblogic,了解weblogic常配参数的意义。通过weblogic自身的监控台,可以了解到目前的JVM的大小、数据库连接池的使用情况以及目前连接的客户端数量以及请求状况等等。
2.学习oracle使用,熟悉它的体系结构,尤其是oracle10里 的awr,awr能采集与统计数据,并从那些统计数据中导出性能量度,以跟踪潜在的问题。
3.需要继续学习LR的理论知识和实际操作,参考书籍《Web性能测试实战》、《软件性能测试过程详解与案例剖析》