02.loadrunner之http接口脚本编写_http脚本-程序员宅基地

技术标签: 性能测试  http接口  脚本详解  

目录

一、前言

二、创建脚本-http

1.通用部分

2.POST:application/x-www-form-urlencoded脚本

3.POST:application/json脚本

4.POST:multipart/form-data脚本

5.GET脚本

三、函数详解

1.lr_start_transaction/lr_end_transaction事务组合

2.web_reg_save_param

3.web_reg_find-检查点函数

四、问题处理


一、前言

本文主要针对http接口GET和POST三种不同的请求类型来编写脚本。
(1)application/x-www-form-urlencoded 键值对
(2)application/json        Json串
(3)multipart/form-data   表单

二、创建脚本-http

1.通用部分

1.Create/Edit Script

2.New Script

3.Web(HTTP/HTML)

4.光标定位于右侧脚本面板,点击菜单Insert -> New step

5.选择Submit Data -> web_submit_data (根绝接口请求类型选择)

6.填入接口相关信息,点击确定生成接口调用内容,然后在修改完善脚本。

2.POST:application/x-www-form-urlencoded脚本

1.选择Submit Data -> web_submit_data,填入接口信息

2.生成脚本如下,点击运行,根据输出信息判断调用成功。

3.完善脚本

光标停留在要插入函数的位置,在INSERT菜单中,选择new step,在列表中选择或查找要插入的函数,根据提示填写必要的参数;

①添加事务

{
	// 定义事务
	/* 通常将一个服务定义为一个事务。这样在性能测试后事务相应时间就能看做一个服务的相应时间
	   事务开始函数 */
	lr_start_transaction("login");

	web_submit_data("login",
		"Action=http://127.0.0.1:8087/hms/login.do",
		"Method=POST",
		"TargetFrame=",
		"Referer=",
		ITEMDATA,
		"Name=username", "Value=nqsq", ENDITEM,
		"Name=password", "Value=a", ENDITEM,
		LAST);

	// 事务结束函数
	lr_end_transaction("login", LR_AUTO);

	return 0;
}

②注册获取返回参数并打印

执行后打印的内容,其中中文出现乱码:

"0"
{"jgbm":"310120101010001","jgmc":"濂夎搐鍖哄崡妗ラ晣绀惧尯鍗敓鏈嶅姟涓績","rybm":"437","ryxm":"鍗楁ˉ绀惧尯","xb":"2","zcjgdm":"42504942400","zcrydm":"006"}
HTTP/1.1 200 
Set-Cookie: JSESSIONID=1A540D4683A6BAD6D01ABA087E99B531; Path=/hms; HttpOnly
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
Access-Control-Max-Age: 86400
Access-Control-Allow-Headers: Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token
Access-Control-Allow-Credentials: true
XDomainRequestAllowed: 1
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 28 Nov 2018 14:31:15 GMT

{"status":"0","data":{"jgbm":"310120101010001","jgmc":"濂夎搐鍖哄崡妗ラ晣绀惧尯鍗敓鏈嶅姟涓績","rybm":"437","ryxm":"鍗楁ˉ绀惧尯","xb":"2","zcjgdm":"42504942400","zcrydm":"006"},"msg":"鐧诲綍鎴愬姛锛?}

③设置检查点(注册断言)

以下代码放在web_submit_data前面

/* 注册断言: Text=断言内容 */
/* 该方法会判断请求响应的内容是否包含status,如果不包含则会报错 */	
web_reg_find("Text=status",
		LAST);

④处理Replay log中输出中文乱码问题

// 将data值从utf-8转为gb2312格式保存在dataStr变量中,并打印
lr_convert_string_encoding(lr_eval_string("{data}"),"utf-8","gb2312","dataStr");
lr_output_message(lr_eval_string("{dataStr}"));

⑤完整内容:

Action()
{
	// 定义事务
	/* 通常将一个服务定义为一个事务。这样在性能测试后事务相应时间就能看做一个服务的相应时间
	   事务开始函数 */
	lr_start_transaction("login");

    /* 注册获取返回参数,该方法可以配合打印返回数据,检测数据内容 */
	web_reg_save_param("status",
					   "LB=\"status\":",
					   "RB=,\"data\":",
					   LAST);
	// 根据左边界值【"data":】和右边界值【,"msg":】搜索响应结果json串中data的值
	web_reg_save_param("data",
					   "LB=\"data\":",
					   "RB=,\"msg\":",
					   LAST);
	// 不指定边界值,保存所有内容
	/* web_reg_save_param("result",
					   "LB=",
					   "RB=",
					   LAST); */

	/* 注册断言: Text=断言内容 */
	/* 该方法会判断请求响应的内容是否包含status,如果不包含则会报错 */	
	web_reg_find("Text=status",
			 LAST);

    /* 向后面的web请求函数增加请求头 */
    /* 如果web请求方法中已经设置了相同的头,则优先使用web请求方法中的头,
	   例如web请求方法中的EncType参数,对应请求投中的Content-Type。
	   由于下面的方法已经设置了EncType参数,所以这里的设置并没有什么X用 */
	/* 表单直接使用方法自带参数,键值对和json建议使用该方法 */
	/* web_add_header("Content-Type",
			   "application/x-www-form-urlencoded; charset=utf-8"); */


    /* 主要针对form表单和键值对两种格式的web请求 */
	web_submit_data("login",
		"Action=http://127.0.0.1:8087/hms/login.do",
		"Method=POST",
		/* 该方法支持常见的两种请求数据格式 */
		/* (1)"EncType=multipart/form-data"。form表单提交数据 */
		/* (1)"EncType=application/x-www-form-urlencoded"。默认使用键值对提交数据 */
		//"EncType=",
		"TargetFrame=",
		"Referer=",
		ITEMDATA,
		"Name=username", "Value=nqsq", ENDITEM,
		"Name=password", "Value=a", ENDITEM,
		LAST);

    /* 打印相应结果 */
    /* lr_eval_string("{result}") 使用loadrunner引用外部函数,
	   只有这样才能取出上面web_reg_save_param方法的返回值 */
	lr_log_message(lr_eval_string("{status}"));
    lr_log_message(lr_eval_string("{data}"));
	// 查看搜索的所有内容
	// lr_log_message(lr_eval_string("{result}"));

	// 将data值从utf-8转为gb2312格式保存在dataStr变量中,并打印
	lr_convert_string_encoding(lr_eval_string("{data}"),"utf-8","gb2312","dataStr");
    lr_output_message(lr_eval_string("{dataStr}"));

	// 事务结束函数
	lr_end_transaction("login", LR_AUTO);

	return 0;
}

3.POST:application/json脚本

未完待续

4.POST:multipart/form-data脚本

未完待续

5.GET脚本

web_custom_request("JYKS01",
		"URL=http://{url}/nethisService.do?action=nethisCommonBusiness&businessCode={businessCode}&businessInfo={businessInfo}",
		"Method=GET",
		"TargetFrame=",
		"Resource=0",                       // 指示URL是否属于资源
		"Referer=",
		LAST);

参数businessInfo需要传utf-8编码后的参数值。

如何传编码前的参数值并且设置编码格式待研究。

三、函数详解

1.lr_start_transaction/lr_end_transaction事务组合

lr_start_transaction为事物开始函数,lr_end_transaction为事物结束函数,并负责记录事物的运行时间。

语法格式如下:
    int lr_start_transaction (const char * transaction_name);

    int lr_end_transaction (const char * transaction_name,int status);

    transacton为事物名称。
    status为事物的结束状态:共有LR_PASS(通过)、LR_FAIL(失败)、LR_AUTO(自动)、 LR_STOP(暂停)。可以在事物结束前通过lr_set_transaction_status进行修改。
    
    如果在lr_end_transaction中没有指定结束事物状态是LR_AUTO,而是明确制定为LR_PASS、LR_FAIL、 LR_STOP其中的一种,则事物将以最后制定状态来结束。

    需要注意,事物开始后需要通过相同的名称以函数lr_end_transaction结束。
       
    

2.web_reg_save_param

定义:注册一个请求,将请求的动态数据信息保存到一个参数。

语法:

int web_reg_save_param(const char *ParamName, <list of Attributes>, LAST);

参数说明:

· ParamName: 存放得到的动态内容的参数名称

· list of Attributes: 其它属性,包括:Notfound, LB, RB, RelFrameID, Search, ORD, SaveOffset, Convert, SaveLen。属性值不分大小写

è¿éåå¾çæè¿°

基本信息: 
1、web_reg_save_param必须在获取返回值的操作前面注册,在获取返回值的操作后面使用 
2、保存参数最大不能超过256字节,如果超过256字节请使用int web_set_max_html_param_len (const char *length )函数扩大参数保存范围
例如:web_set_max_html_param_len ("1024"); //扩大参数最大保存范围为1024字节
3、LB和RB后面跟着"/ic",则边界大小写都匹配(不加,也就是默认是大小写敏感的);在边界之后指定“/BIN”,即RB/BIN、RB/BIN,则表示为二进制数据 ;
例如:web_reg_save_param("IsRight","LB/ic=cache-control: private\r\n\r\n","RB/ic=|",LAST);
4、属性值不区分大小写,如”Search=all”

附:

一、什么是关联

关联(correlation):脚本回放过程中,客户端发出请求,通过关联函数所定义的左右边界值(也就是关联规则),在服务器所响应的内容中查找,得到相应的值,已变量的形式替换录制时的静态值,从而向服务器发出正确的请求,这种动态获得服务器响应内容的方法被称作关联。也是把脚本中某些写死的数据,转变成动态的数据。
什么内容需要关联:当脚本中的数据每次回放都发生变化时,并且这个动态数据在后面的请求中需要发送给服务器,那么这个内容需要通过关联来询问服务器,获得该数据的变化结果。例如:
1.登录字符串。带有会话 ID 或时间戳等动态数据的登录字符串。
2.日期/时间戳。使用日期或时间戳或者其他用户凭据的任意字符串。
3.常见前缀。后跟字符串的常见前缀,如 SessionID 或 CustomerID

二、手工关联

web_reg_save_param 函数一般用于LR中进行手工关联,运行脚本时,web_reg_save_param 函数将扫描所访问的后续 HTML 页。如果指定左边界和/ 或右边界, VuGen 将搜索这些边界之间的文本。VuGen 找到文本后,会将其分配给某个参数。

举个例子说明吧:

比如说对源码中的<input type="hidden" id="orderId" name="orderId" value="f28958249e141e62312d855ce73252d3"/>的orderId的值进行关联,那么我们可以这样写:

web_reg_save_param("orderId",
   "LB=name=\"orderId\" value=\"",
   "RB=\"",
   LAST);

这个就是要在整个HTML文件中找,左边界是:name="orderId" value="        右边界是:"

的中间文本的值,找到后赋给orderId。

资料:

https://blog.csdn.net/jiang1986829/article/details/47113613 

https://blog.csdn.net/brbrbrbrbrbr/article/details/52404552

3.web_reg_find-检查点函数

LR检查点

  设置检查点的目的不只是为了验证我们的脚本没有错误,而更重要的是一个规范问题,如何使得测试结果更具有说服力,因此建议所有的测试脚本中都添加检查点设置。

 一、设置检查点的方法

1.将脚本切换到树结构,在page view页面上找到你要check的文本内容, 并执行鼠标右键,选择Add a text check.

2.将脚本切换回代码界面,在光标闪烁的上行,手动添加如下的代码

web_reg_find("Text/IC=Payment Details", "SaveCount=para_count", LAST);

这里是要运行的页面脚本

if (atoi(lr_eval_string("{para_count}"))>0)        //验证是否找到了页面上的要检查的字符串

    lr_output_message("Pass!");

 else

  lr_output_message("Failed!");

注意:

l   “Payment Details” 为你要检查的文本;

l   脚本执行到此处,不管页面上是否存在你要检查的字符串,脚本都不会报错,而是执行下去。

l   此段代码将找到的你要检查的字符串的个数,存为一个参数。 然后在页面代码的后面,通过检查这个参数的值是否大于0,来判断是否找到了你所要检查的字符串。

l   这里的测试结果均以200状态码返回,其失败的结果将在分析报告中进行分类标识。

//atoi()函数的作用是将一个ASCII字符串转换为整型

//lr_eval_string()函数作用是取得参数值,将字符串变量中的参数值替换为当前的参数值并将这个字符串返回

资料:

https://www.cnblogs.com/lci05/p/3647698.html

四、问题处理

1.replaylog中的中文乱码

解决这个问题必须认识到一个事实就是,loadrunner和测试服务器交换数据使用的是utf8格式,但是展现在replaylog中是使用gb2312格式, 而且在脚本中如何使用web_reg_find的时候也是使用的是gb2312格式,所以知道这个原理后,事情就好办多了。 

1.获取测试服务器提供的utf8格式的文字并且转换成gb2312格式展现出来
        web_reg_save_param_ex(
          "ParamName=aa",
          "LB=ProductName",
          "RB=ProductBriefName",
          "NotFound=warning",
          SEARCH_FILTERS,
          LAST)     ;    


     web_url("web_url",
          "URL=http://124.238.214.65:70/Scripts/Home/HomeHotProduct.js",
          "TargetFrame=",
          "Resource=0",
          "Referer=",
          LAST);
    lr_convert_string_encoding(lr_eval_string("{aa}"),"utf-8","gb2312","str");
    lr_output_message(lr_eval_string("{str}"));


2.本地的gb2312的中文经过转换成utf8发给测试服务器

       lr_convert_string_encoding(lr_eval_string("智能手机"),"gb2312","utf-8","a1");
          web_reg_save_param_ex(
          "ParamName=aa",
          "LB={a1}",
          "RB=",
          "NotFound=error",
          SEARCH_FILTERS,
          LAST);

          web_url("IndexCategoryProductJson.js",
          "URL=http://124.238.214.65:70/Scripts/Home/IndexCategoryProductJson.js",
          "Resource=1",
          "RecContentType=application/x-javascript",
          "Referer=http://124.238.214.65:8081/",
          "Snapshot=t24.inf",
          LAST);

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/angel1magic/article/details/84591985

智能推荐

艾美捷Epigentek DNA样品的超声能量处理方案-程序员宅基地

文章浏览阅读15次。空化气泡的大小和相应的空化能量可以通过调整完全标度的振幅水平来操纵和数字控制。通过强调超声技术中的更高通量处理和防止样品污染,Epigentek EpiSonic超声仪可以轻松集成到现有的实验室工作流程中,并且特别适合与表观遗传学和下一代应用的兼容性。Epigentek的EpiSonic已成为一种有效的剪切设备,用于在染色质免疫沉淀技术中制备染色质样品,以及用于下一代测序平台的DNA文库制备。该装置的经济性及其多重样品的能力使其成为每个实验室拥有的经济高效的工具,而不仅仅是核心设施。

11、合宙Air模块Luat开发:通过http协议获取天气信息_合宙获取天气-程序员宅基地

文章浏览阅读4.2k次,点赞3次,收藏14次。目录点击这里查看所有博文  本系列博客,理论上适用于合宙的Air202、Air268、Air720x、Air720S以及最近发布的Air720U(我还没拿到样机,应该也能支持)。  先不管支不支持,如果你用的是合宙的模块,那都不妨一试,也许会有意外收获。  我使用的是Air720SL模块,如果在其他模块上不能用,那就是底层core固件暂时还没有支持,这里的代码是没有问题的。例程仅供参考!..._合宙获取天气

EasyMesh和802.11s对比-程序员宅基地

文章浏览阅读7.7k次,点赞2次,收藏41次。1 关于meshMesh的意思是网状物,以前读书的时候,在自动化领域有传感器自组网,zigbee、蓝牙等无线方式实现各个网络节点消息通信,通过各种算法,保证整个网络中所有节点信息能经过多跳最终传递到目的地,用于数据采集。十多年过去了,在无线路由器领域又把这个mesh概念翻炒了一下,各大品牌都推出了mesh路由器,大多数是3个为一组,实现在面积较大的住宅里,增强wifi覆盖范围,智能在多热点之间切换,提升上网体验。因为节点基本上在3个以内,所以mesh的算法不必太复杂,组网形式比较简单。各厂家都自定义了组_802.11s

线程的几种状态_线程状态-程序员宅基地

文章浏览阅读5.2k次,点赞8次,收藏21次。线程的几种状态_线程状态

stack的常见用法详解_stack函数用法-程序员宅基地

文章浏览阅读4.2w次,点赞124次,收藏688次。stack翻译为栈,是STL中实现的一个后进先出的容器。要使用 stack,应先添加头文件include<stack>,并在头文件下面加上“ using namespacestd;"1. stack的定义其定义的写法和其他STL容器相同, typename可以任意基本数据类型或容器:stack<typename> name;2. stack容器内元素的访问..._stack函数用法

2018.11.16javascript课上随笔(DOM)-程序员宅基地

文章浏览阅读71次。<li> <a href = "“#”>-</a></li><li>子节点:文本节点(回车),元素节点,文本节点。不同节点树:  节点(各种类型节点)childNodes:返回子节点的所有子节点的集合,包含任何类型、元素节点(元素类型节点):child。node.getAttribute(at...

随便推点

layui.extend的一点知识 第三方模块base 路径_layui extend-程序员宅基地

文章浏览阅读3.4k次。//config的设置是全局的layui.config({ base: '/res/js/' //假设这是你存放拓展模块的根目录}).extend({ //设定模块别名 mymod: 'mymod' //如果 mymod.js 是在根目录,也可以不用设定别名 ,mod1: 'admin/mod1' //相对于上述 base 目录的子目录}); //你也可以忽略 base 设定的根目录,直接在 extend 指定路径(主要:该功能为 layui 2.2.0 新增)layui.exten_layui extend

5G云计算:5G网络的分层思想_5g分层结构-程序员宅基地

文章浏览阅读3.2k次,点赞6次,收藏13次。分层思想分层思想分层思想-1分层思想-2分层思想-2OSI七层参考模型物理层和数据链路层物理层数据链路层网络层传输层会话层表示层应用层OSI七层模型的分层结构TCP/IP协议族的组成数据封装过程数据解封装过程PDU设备与层的对应关系各层通信分层思想分层思想-1在现实生活种,我们在喝牛奶时,未必了解他的生产过程,我们所接触的或许只是从超时购买牛奶。分层思想-2平时我们在网络时也未必知道数据的传输过程我们的所考虑的就是可以传就可以,不用管他时怎么传输的分层思想-2将复杂的流程分解为几个功能_5g分层结构

基于二值化图像转GCode的单向扫描实现-程序员宅基地

文章浏览阅读191次。在激光雕刻中,单向扫描(Unidirectional Scanning)是一种雕刻技术,其中激光头只在一个方向上移动,而不是来回移动。这种移动方式主要应用于通过激光逐行扫描图像表面的过程。具体而言,单向扫描的过程通常包括以下步骤:横向移动(X轴): 激光头沿X轴方向移动到图像的一侧。纵向移动(Y轴): 激光头沿Y轴方向开始逐行移动,刻蚀图像表面。这一过程是单向的,即在每一行上激光头只在一个方向上移动。返回横向移动: 一旦一行完成,激光头返回到图像的一侧,准备进行下一行的刻蚀。

算法随笔:强连通分量-程序员宅基地

文章浏览阅读577次。强连通:在有向图G中,如果两个点u和v是互相可达的,即从u出发可以到达v,从v出发也可以到达u,则成u和v是强连通的。强连通分量:如果一个有向图G不是强连通图,那么可以把它分成躲个子图,其中每个子图的内部是强连通的,而且这些子图已经扩展到最大,不能与子图外的任一点强连通,成这样的一个“极大连通”子图是G的一个强连通分量(SCC)。强连通分量的一些性质:(1)一个点必须有出度和入度,才会与其他点强连通。(2)把一个SCC从图中挖掉,不影响其他点的强连通性。_强连通分量

Django(2)|templates模板+静态资源目录static_django templates-程序员宅基地

文章浏览阅读3.9k次,点赞5次,收藏18次。在做web开发,要给用户提供一个页面,页面包括静态页面+数据,两者结合起来就是完整的可视化的页面,django的模板系统支持这种功能,首先需要写一个静态页面,然后通过python的模板语法将数据渲染上去。1.创建一个templates目录2.配置。_django templates

linux下的GPU测试软件,Ubuntu等Linux系统显卡性能测试软件 Unigine 3D-程序员宅基地

文章浏览阅读1.7k次。Ubuntu等Linux系统显卡性能测试软件 Unigine 3DUbuntu Intel显卡驱动安装,请参考:ATI和NVIDIA显卡请在软件和更新中的附加驱动中安装。 这里推荐: 运行后,F9就可评分,已测试显卡有K2000 2GB 900+分,GT330m 1GB 340+ 分,GT620 1GB 340+ 分,四代i5核显340+ 分,还有写博客的小盒子100+ 分。relaybot@re...

推荐文章

热门文章

相关标签