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

时间:2023-01-31 20:09:43

一、前言:

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

二、准备:

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

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

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

三、实现过程:

3.1 脚本主体

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

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

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

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

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

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

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

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

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

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

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

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

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

  写入General信息:

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

  写入参数信息:

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

  点击确定后生成脚本。创建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】,创建新的参数。

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

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

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

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

3.2.2 Mysql数据库数据获取

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

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

  Next

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

  Next

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

  Next

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

  Next

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

  Next

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

  Next

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

  Next,写入sql语句

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

  数据已导入:

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

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

3.3 检查点设置

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

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

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

HTTP/1.1  Found
Date: Sun, Dec :: GMT
Server: Apache/2.4. (Unix) OpenSSL/1.0.1f PHP/5.5. mod_perl/2.0.-dev Perl/v5.16.3
X-Powered-By: PHP/5.5.
Expires: Thu, Nov :: GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=, pre-check=
Pragma: no-cache
Set-Cookie: PHPSESSID=a3dta30c68sb9l7fc9t4ancp03; path=/
Set-Cookie: language=deleted; expires=Thu, -Jan- :: GMT; Max-Age=; path=/
Set-Cookie: language=bece46be16477e1ab82f9d40a53074cb0a54e105s%3A5%3A%22zh_cn%%3B; expires=Tue, -Jan- :: GMT; Max-Age=; path=/
Location: http://192.168.232.128/bugfree/index.php
Content-Length:
Keep-Alive: timeout=, max=
Connection: Keep-Alive
Content-Type: text/html

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

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

  再观察其响应内容,状态码是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表示注册型函数,这类函数作用于其下文第一个函数。

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

  生成脚本如下:

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(): Registered web_reg_find successful for "Text=302" (count=)      [MsgId: MMSG-]
Action.c(): web_submit_data("login") was successful, body bytes, header bytes, chunking overhead bytes [MsgId: MMSG-]

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

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

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

3.3 关联设置

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

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

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

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

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

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

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

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

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

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

  生成脚本如下:

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

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

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

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

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

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

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

  再次运行脚本:

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

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

3.4 脚本调试

  脚本调试应遵循分步调试原则,可以采用【断点设置】和【单步跟踪】。更简便的方法就是利用注释,比如,先将【创建缺陷】、【解决缺陷】注释,单独放开【登录】,对其进行调试,由上至下依次进行。

  通过View--Test result可查看Html格式视图,便于排查脚本中的错误。例如下图,表明UTF-8未设置,导致中文参数值不被识别:

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

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

  1. LoadRunner系列之—-02 基于webservice协议的接口测试(脚本实例)

    Loadrunner 基于webservice协议的接口压力测试(脚本实例) 接口功能如下:请求接口,报文只有一个参数为证件号码:返回报文中,有证件号码是否能查到对应数据,查到几条数据. 思路:请求w ...

  2. 手动编写一个简单的loadrunner脚本

    loadrunner除了自动录制脚本外,还可以手动编写脚本,通过右键+inset step添加步骤,还可以手动添加事务,集合点等 下面是一个简单的Action脚本,服务是运行在本机的flask服务: ...

  3. LoadRunner ---手动关联与预关联

    手动关联                                       如果脚本很长,那么我们想找到一个脚本中哪些地方是需要关联的并不是一件容易的事情.这时,我们可以通过脚本对比的方法找 ...

  4. 【Loadrunner】Loadrunner 手动关联技术

    Loadrunner 手动关联技术 录制成功,回放失败,怀疑和动态数据有关: 1 重新录制一份脚本,两次录制的脚本进行比对,确定动态数据,复制动态数据: 2  找到第一次产生该动态数据的响应对应的相应 ...

  5. Loadrunner手动关联详解

    Loadrunner手动关联详解 一.关联的含义: 关联(correlation):在脚本回放过程中,客户端发出请求,通过关联函数所定义的左右边界值(也就是关联规则),在服务器所响应的内容中查找,得到 ...

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

    LoadRunner关联函数的脚本实例--如何操作关联参数 这几天一直在学习LoadRunner的VuGen编程,今天想对关联函数web_reg_save_param做详细的试验和研究: ~f6p q ...

  7. 性能测试基础---事务&amp&semi;检查点&amp&semi;思考时间&amp&semi;集合点

    性能测试脚本的增强:·参数化·关联·事务·检查点·思考时间·集合点 ·事务:事务的引入是为了度量相关的业务请求的响应时间和吞吐量指标.在LR中,事务是通过两个事务函数来实现的. lr_start_tr ...

  8. 软件测试之loadrunner学习笔记-01事务

    loadrunner学习笔记-01事务<转载至网络> 事务又称为Transaction,事务是一个点为了衡量某个action的性能,需要在开始和结束位置插入一个范围,定义这样一个事务. 作 ...

  9. 性能测试总结工作总结-基于WebService协议脚本 内置函数手动编写

    LoadRunner基于WebService协议脚本 WebService协议脚本有三种生成方式,一种是直接通过LoadRunner导入URL自动解析生成:一种是使用LoadRunner内置函数手动编 ...

随机推荐

  1. CSS Sticky Footer

    ----CSS Sticky Footer 当正文内容很少时,底部位于窗口最下面.当改变窗口高度时,不会出现重叠问题. ----另一个解决方法是使用:flexBox布局  http://www.w3c ...

  2. ABySS 拼接工具

    ABySS, that stands for Assembly By Short Sequences, is a de novo, parallel, paired-end sequence asse ...

  3. 最大化 AIX 上的 Java 性能,第 1 部分&colon; 基础

    http://www.ibm.com/developerworks/cn/aix/library/es-Javaperf/es-Javaperf1.html 最大化 AIX 上的 Java 性能,第 ...

  4. 【BZOJ】【1552】【Cerc2007】robotic sort &sol; 【3506】【CQOI2014】排序机械臂

    Splay 离散化+Splay维护序列…… 好吧主要说一下我做这道题遇到的几个错误点: 1.离散化 2.由于找到的这个数的位置一定是大于等于 i 的,所以其实在把它splay到根以后,i 结点只能sp ...

  5. uimodalpresentationformsheet resize ios7

    CROHomeCRAAddController *temp =[[CROHomeCRAAddControlleralloc] init]; temp.modalTransitionStyle = UI ...

  6. CSS布局中——导航是非常常见的

    导航绝对是页面布局中最常见的,为了不用每次去写,稍微贴个简单的导航模版出来,方便以后使用. <title>CSS菜单</title> <style type=" ...

  7. ArcGIS Runtime SDK for Android开发之调用GP服务(异步调用)

    一.背景说明 通过调用GP服务,Android客户端也能实现专业的.复杂的GIS分析处理功能,从而增加应用的实用价值. ArcGIS Server发布的GP服务,分为同步和异步两种类型,一般执行步骤较 ...

  8. Java 学习笔记 使用并发包ReentrantLock简化生产者消费者模式代码

    说明 ReentrantLock是java官方的一个线程锁类,ReentarntLock实现了Lock的接口 我们只需要使用这个,就可以不用使用synchronized同步关键字以及对应的notify ...

  9. fiddler抓取https请求

    Fiddler抓取https设置详解(图文):https://www.cnblogs.com/joshua317/p/8670923.html Fiddler要抓取到https请求我们还需要Fiddl ...

  10. 利用&sol;dev&sol;urandom文件创建随机数

    1:/dev/urandom和/dev/random是什么 这两个文件记录Linux下的熵池,所谓熵池就是当前系统下的环境噪音,描述了一个系统的混乱程度,环境噪音由这几个方面组成,如内存的使用,文件的 ...