Loadrunner手动编写包含检查点、关联等元素的脚本实例

一、前言:

本文适合初学者,包含很多细节,也作为自己的备忘。有不准确之处,欢迎指正。

二、准备:

1、以虚拟机中的Linux系统作为服务器,开启bugfree服务。

2、以fiddler作为抓包工具,辅助脚本开发。

3、脚本流程:bugfree登录--创建bug--解决bug。

三、实现过程:

3.1 脚本主体

创建空白脚本后,结构如下图,压力测试中一般我们将登录单独放在vuser_init中。这里为了整个流程更清晰,脚本全部写在Action中。

  

值得注意的是,我们设置脚本迭代次数,只对Action部分生效,而vuser_init和vuser_end只会运行一次。

  

开始写脚本前,我们对fiddler先进行一些过滤设置。

  

  在浏览器进行bugfree登录操作,fiddler抓取到结果,比较有用的信息是URL以及Headers项的请求类型(这里是POST)、参数列表。

  

  

  如果参数中以及后文的检查点文本中含有中文,需要设置loadrunner支持UTF-8编码格式,将含有UTF-8的项改为“Yes”:

  

  在已知请求类型为POST的前提下,执行Insert--new step--Submit Data。如果是GET请求,则需要插入Url函数。

  

  写入General信息:

  

  写入参数信息:

  

  点击确定后生成脚本。创建bug和解决bug与此类似,生成脚本如下:

 web_submit_data("创建缺陷",
        "Action=http://192.168.232.132/bugfree/info/edit?type=bug&action=opened&product_id=1",
        "Method=POST",
        "TargetFrame=",
        "Referer=",
        "Mode=HTTP",
        ITEMDATA,
        "Name=BugInfoView[deleted_file_id]", "Value=", ENDITEM,
        "Name=BugInfoView[lock_version]", "Value=", ENDITEM,
        "Name=BugInfoView[product_id]", "Value=1", ENDITEM,
        "Name=isPageDirty", "Value=1", ENDITEM,
        "Name=templateTitle", "Value=", ENDITEM,
        "Name=BugInfoView[title]", "Value=mutest20170927{title}", ENDITEM,
        "Name=layer1_module", "Value=0", ENDITEM,
        "Name=BugInfoView[productmodule_id]", "Value=0", ENDITEM,
        "Name=BugInfoView[assign_to_name]", "Value=系统管理员", ENDITEM,
        "Name=BugInfoView[mail_to]", "Value=", ENDITEM,
        "Name=BugInfoView[severity]", "Value=1", ENDITEM,
        "Name=BugInfoView[priority]", "Value=1", ENDITEM,
        "Name=Custom[BugType]", "Value=代码错误", ENDITEM,
        "Name=Custom[HowFound]", "Value=代码检查", ENDITEM,
        "Name=Custom[BugOS]", "Value=Linux", ENDITEM,
        "Name=Custom[BugBrowser]", "Value=Chrome", ENDITEM,
        "Name=Custom[OpenedBuild]", "Value=Mu", ENDITEM,
        "Name=Custom[ResolvedBuild]", "Value=", ENDITEM,
        "Name=Custom[BugSubStatus]", "Value=", ENDITEM,
        "Name=Custom[BugMachine]", "Value=", ENDITEM,
        "Name=Custom[BugKeyword]", "Value=", ENDITEM,
        "Name=BugInfoView[related_bug]", "Value=", ENDITEM,
        "Name=BugInfoView[related_case]", "Value=", ENDITEM,
        "Name=BugInfoView[related_result]", "Value=", ENDITEM,
        "Name=attachment_file[]", "Value=", ENDITEM,
        "Name=BugInfoView[action_note]", "Value=", ENDITEM,
        "Name=BugInfoView[repeat_step]", "Value=<br />", ENDITEM,
        LAST);

    web_submit_data("解决缺陷",
        "Action=http://192.168.232.132/bugfree/bug/1/resolved",
        "Method=POST",
        "TargetFrame=",
        "Referer=",
        "Mode=HTTP",
        ITEMDATA,
        "Name=BugInfoView[deleted_file_id]", "Value=", ENDITEM,
        "Name=BugInfoView[lock_version]", "Value=1", ENDITEM,
        "Name=BugInfoView[product_id]", "Value=1", ENDITEM,
        "Name=isPageDirty", "Value=1", ENDITEM,
        "Name=templateTitle", "Value=", ENDITEM,
        "Name=BugInfoView[title]", "Value=mutest20170927{title}", ENDITEM,
        "Name=layer1_module", "Value=0", ENDITEM,
        "Name=BugInfoView[productmodule_id]", "Value=0", ENDITEM,
        "Name=BugInfoView[assign_to_name]", "Value=系统管理员", ENDITEM,
        "Name=BugInfoView[mail_to]", "Value=", ENDITEM,
        "Name=BugInfoView[severity]", "Value=1", ENDITEM,
        "Name=BugInfoView[priority]", "Value=1", ENDITEM,
        "Name=Custom[BugType]", "Value=代码错误", ENDITEM,
        "Name=Custom[HowFound]", "Value=代码检查", ENDITEM,
        "Name=Custom[BugOS]", "Value=全部", ENDITEM,
        "Name=Custom[BugBrowser]", "Value=Chrome", ENDITEM,
        "Name=Custom[OpenedBuild]", "Value=Mu", ENDITEM,
        "Name=Custom[ResolvedBuild]", "Value=Mu", ENDITEM,
        "Name=BugInfoView[solution]", "Value=By Design", ENDITEM,
        "Name=BugInfoView[duplicate_id]", "Value=", ENDITEM,
        "Name=Custom[BugSubStatus]", "Value=Hold", ENDITEM,
        "Name=Custom[BugMachine]", "Value=", ENDITEM,
        "Name=Custom[BugKeyword]", "Value=", ENDITEM,
        "Name=BugInfoView[related_bug]", "Value=", ENDITEM,
        "Name=BugInfoView[related_case]", "Value=", ENDITEM,
        "Name=BugInfoView[related_result]", "Value=", ENDITEM,
        "Name=attachment_file[]", "Value=", ENDITEM,
        "Name=BugInfoView[action_note]", "Value=", ENDITEM,
        "Name=BugInfoView[repeat_step]", "Value=<br />", ENDITEM,
        LAST);

  至此,脚本主体完成。但这样的脚本很显然是不符合压测要求的:

  1、如果对登录单独压测,因为登录是查询型请求,与修改型请求不同,我们在数据库中无从校验其成功率。所以设置登录检查点函数是必要的。

  2、如果登录用户名不允许多IP同时登录,那么对用户名进行参数化是必要的。参数化的本质是应对数据库对参数值进行的唯一性校验。

  3、观察脚本,解决Bug步骤,其Bug ID是固定的,那么执行压测时,我们就一直在对同一个Bug进行解决缺陷操作,这显然是不合理的。我们需要将Bug ID和上一步创建Bug的Bug ID关联起来。这样,才能保证每次解决缺陷都是针对上一步刚刚创建的处于未解决状态的Bug。

  接下来,对脚本进行改进:

3.2 参数化

  参数化设置的目的是应对数据库对参数值的唯一性校验。其设置方式如下:

3.1.1 参数化设置

  打开Parameter List,点击左下角的【New】,创建新的参数。

  

  生成之后,右键选中待替换内容,选择【Use Existing Parameter】:

  

  或者,也可以直接选中待参数化内容,右键后选择【Replace with a Parameter】,一次性进行创建参数和替换。

3.2.2 Mysql数据库数据获取

  设置参数化之后,面临的问题就是大量数据从何而来。利用存储过程在数据库中创建大量数据,然后参数化文件读取这些数据,是个不错的方法。

  

  Next

  

  Next

  

  Next

  

  Next

  

  Next

  

  Next

  

  Next,写入sql语句

  

  数据已导入:

  

  参数类型即Parameter type还可选择其他类型,常用的如Date/Time,Rondom Nunmber(可用于注册型请求的用户名参数)等,遇到实际场景后补充。

3.3 检查点设置

  以登录为例,只要我们提交了请求,即使不能成功登录,服务器返回给我们的状态码依然是200,而loadrunner判断请求是否成功的依据就是返回的状态码,所以在未加检查点之前,我们无从判断登录业务是否成功。当然,非查询类请求,可以去数据库进行校验。

  因此我们需要加入检查点来进行业务是否真正成功的校验。检查点的思想是,在请求响应内容中,查找特殊字段,例如登录请求响应中的“欢迎”、“退出”等等字段。下面以Bug登录为例,进行检查点详细解析。

  首先,我们去分析登录请求中,检查点需要设置的文本内容。

HTTP/1.1 302 Found
Date: Sun, 10 Dec 2017 10:07:38 GMT
Server: Apache/2.4.7 (Unix) OpenSSL/1.0.1f PHP/5.5.9 mod_perl/2.0.8-dev Perl/v5.16.3
X-Powered-By: PHP/5.5.9
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=a3dta30c68sb9l7fc9t4ancp03; path=/
Set-Cookie: language=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/
Set-Cookie: language=bece46be16477e1ab82f9d40a53074cb0a54e105s%3A5%3A%22zh_cn%22%3B; expires=Tue, 09-Jan-2018 10:07:39 GMT; Max-Age=2592000; path=/
Location: http://192.168.232.128/bugfree/index.php
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

  在响应内容中,貌似没有特殊字段。只有“302”值得注意,这个状态码表示请求发生重定向,对象已临时移动。那么,也只有登录成功之后,才能进行跳转首页的重定向。为了验证该结论,我做一次失败登录。第二次失败登录与第一次成功登录相比,缺少了后续跳转首页等请求。

  

  再观察其响应内容,状态码是200。至此,我们可以选定登录检查点函数的检查文本为“302”。

HTTP/1.1 200 OK
Date: Sun, 10 Dec 2017 11:07:03 GMT
Server: Apache/2.4.7 (Unix) OpenSSL/1.0.1f PHP/5.5.9 mod_perl/2.0.8-dev Perl/v5.16.3
X-Powered-By: PHP/5.5.9
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4039
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

  执行Insert--new step--web_reg_find,reg表示注册型函数,这类函数作用于其下文第一个函数。

  

  生成脚本如下:

web_reg_find("Fail=NotFound",
		"Search=All",
		"SaveCount=count",
		"Text=302",
		LAST);

	web_submit_data("login",
		"Action=http://192.168.232.128/bugfree/index.php/site/login",
		"Method=POST",
		"TargetFrame=",
		"Referer=",
		"Mode=HTTP",
		ITEMDATA,
		"Name=LoginForm[username]", "Value=admin", ENDITEM,
		"Name=LoginForm[password]", "Value=123456", ENDITEM,
		"Name=LoginForm[language]", "Value=zh_cn", ENDITEM,
		"Name=LoginForm[rememberMe]", "Value=0", ENDITEM,
		LAST);

  运行脚本:

Action.c(10): Registered web_reg_find successful for "Text=302" (count=2)      [MsgId: MMSG-26364]
Action.c(10): web_submit_data("login") was successful, 76514 body bytes, 1898 header bytes, 14 chunking overhead bytes      [MsgId: MMSG-26385]

  回到脚本中,修改密码为“1234567”,运行脚本进行反向验证:

Action.c(10): Error -26366: "Text=302" not found for web_reg_find      [MsgId: MERR-26366]
Action.c(10): web_submit_data("login") highest severity level was "ERROR", 4041 body bytes, 465 header bytes      [MsgId: MMSG-26388]

  至此,检查点设置成功。检查点特殊文本内容的确定需要一点点自己的分析。

3.3 关联设置

  一、为什么要设置关联,常见场景有以下两个:

  1、登录请求中,含有formhash、sessionid等特殊参数,这些参数的值每次请求将发生更新,而脚本中如果将其固定,下次请求仍然提交上次使用的参数值,请求将会失败。

  2、创建缺陷生成Bug ID,解决缺陷请求依赖该Bug ID,请求参数中Bug ID的值需要随着创建缺陷生成的Bug ID同步更新。

  下面以Bugfree解决缺陷为例,讲述如何设置关联:

  首先,在【创建缺陷】请求的响应中查找“57730”,该ID是我新创建的。

  

  截取其中一段包含“57730”的字段:

location=‘/bugfree/index.php/bug/57730‘;</

  执行Insert--new step--web_reg_save_param,其中BugID是参数名,具备一定意义即可,后续请求需要引用该参数名。

  

  生成脚本如下:

web_reg_save_param("BugID",
        "LB=location=‘/bugfree/index.php/bug/",
        "RB=‘;</",
        "Search=All",
        LAST);

  为了查看关联参数捕捉情况,开启扩展日志:

  运行脚本,观察Replay Log,关联参数捕捉成功:

Action.c(23): Registering web_reg_save_param was successful      [MsgId: MMSG-26390]
Action.c(29): Notify: Saving Parameter "BugID = 57732".

  关联参数捕捉结束,接下来很简单,传递捕获的参数到后续请求中,将具体值替换成引用值即可:

  

  再次运行脚本:

Action.c(23): Registering web_reg_save_param was successful      [MsgId: MMSG-26390]
Action.c(29): Notify: Saving Parameter "BugID = 57734".
Action.c(29): web_submit_data("创建缺陷") was successful, 28553 body bytes, 412 header bytes, 25 chunking overhead bytes      [MsgId: MMSG-26385]
Action.c(65): Notify: Parameter Substitution: parameter "BugID" =  "57734"
Action.c(65): web_submit_data("解决缺陷") was successful, 30589 body bytes, 412 header bytes, 25 chunking overhead bytes      [MsgId: MMSG-26385]

  关联基本应用到此为止,后续补充复杂的关联应用,例如关联数组。

3.4 脚本调试

  脚本调试应遵循分步调试原则,由上至下。比如,先将【创建缺陷】、【解决缺陷】注释,单独放开【登录】,对其进行调试。通过View--Test result可查看Html格式视图,便于排查脚本中的错误。例如下图,表明UTF-8未设置,导致中文参数值不被识别:

  

时间: 2024-11-08 07:15:56

Loadrunner手动编写包含检查点、关联等元素的脚本实例的相关文章

Loadrunner手动关联详解

Loadrunner手动关联详解 一.关联的含义: 关联(correlation):在脚本回放过程中,客户端发出请求,通过关联函数所定义的左右边界值(也就是关联规则),在服务器所响应的内容中查找,得到相应的值,已变量的形式替换录制时的静态值,从而向服务器发出正确的请求,这种动态获得服务器响应内容的方法被称作关联. 二.关联的过程: 以登陆场景为例,客户端发出获得登录页面的请求,服务器端得到该请求后,返回登录页面,同时动态生成一个Session Id,当用户输入用户名密码,请求登录时,该Sessi

loadrunner提高篇-插入检查点与关联函数

插入检查点   靠LR自动生成的脚本是不够的,很难达到业务要求,因此需要对录制完的脚本进行完善,使其能达到业务模拟的要求 ,这样尽可能地使虚拟用户模拟时更接近用户的实际使用. 在进行压力测试时,经常会有页面间数据传递的操作.如果在测试过程中传递数据的次数逐渐增多,页面就有可能发生传递混乱,或者客户端与服务器端数据传输被中断.传输过程中产生了错误的数据等情况.为了判断数据传递的正确性,LR提供了插入检查点的方法.之前在入门篇的博客中有提到插入检查点的原因,这里就不再细说了,大概提一下,是因为当事务

LoadRunner关联函数的脚本实例--如何操作关联参数

LoadRunner关联函数的脚本实例--如何操作关联参数 这几天一直在学习LoadRunner的VuGen编程,今天想对关联函数web_reg_save_param做详细的试验和研究: ~f6p q+Z  RM0 a6_%_+vF9Ws\w&S0 问题提出:如何对关联的数据进行字符串操作.下面使用了LoadRunner自带的订票例子为例,进行了这方面的试验.假设我要关联的数据是由几个字符串组成的.如何使这些字符串组成一个参数,供我后面的函数使用?51Testing软件测试网.VZR(`D&quo

wap图片滚动特效_无css3 元素js脚本编写

手机图片滑动切换,网上有很多这样的例子,但都借助于其他组件,让代码混乱的不行:还有就是用到css3里的 transform:translate(x,y);移动元素,不过发现在不支持css3的设备上马上完蛋了,所 有下定决心自己做一个,谁知出现了很多的问题,其中最重要的是给图片加链接,网页中的上下滚动条不能在拖动图片的时候滚动,并且不能兼容pc机器上的拖动:在这里就简单介绍一下遇到的问题和解决的方法: 问题一:给图片加上链接后,在拖动的时候总是跳到其他页面: 问题根源主要是不能判断是点击还是拖动,

qtday01 ubuntu 下手动编写第一个qt程序

//qt 5.2.1 //1t目录下 //1t.cpp /* 第一个qt程序 */ #include <QApplication> #include<QtWidgets/QLabel> #include<QString> #include<QTextCodec> int main(int argc,char** argv){ /*构造一个对象*/ QApplication app(argc,argv); QTextCodec* coder=QTextCode

44.从键盘输入12个数存入二维数组a[3][4]中,编写程序求出最大元素的值及它所在的行号和列号

//1.建立二维数组 //2.运用循环,将内容输入到数组中 //3.求出最大元素,并输出行号和列号 #include<iostream> using namespace std; int main() { int a[3][4]; int Max=0;//赋值之前需要先置为0 cout<<"please input 12 numbers: "<<endl; for(int i=0;i<3;i++)//嵌套循环,用于向二维数组中输入内容 { fo

匹配包含给定文本的元素

描述: 查找所有包含 "John" 的 div 元素 HTML 代码: <div>John Resig</div> <div>George Martin</div> <div>Malcom John Sinclair</div> <div>J. Ohn jQuery 代码: $("div:contains('John')") 结果: [ <div>John Resig&l

[ jquery 选择器 :contains(text) ] 此方法选取包含给定文本的元素

匹配包含给定文本的元素,参数解析如下: 1.text:给定文本 实例: <!DOCTYPE html> <html lang='zh-cn'> <head> <title>Insert you title</title> <meta http-equiv='description' content='this is my page'> <meta http-equiv='keywords' content='keyword1,k

.has()——选取包含某条件的元素

描述:选择元素内部是否存在包含给定条件的元素 写法:$("元素").has("class或id值等") 注意:与.filter()的区别 $("div").has("span").css("background","red"); <div>div1<span>span</span></div> 这个变色 <div>div2<