Jmeter使用笔记(本文偏"接口测试工具")【GET/POST的HTTP请求、请求头、响应断言、正则表达式提取器、CSV读取参数、跨线程组传递变量】

转自:http://www.cnblogs.com/LiangHu/tag/Jmeter/

一、运行一个HTTP请求

自从毕业从事软件测试行业,大多数时间都在跟各种API打交道,使用过的接口测试工具也有许多,本文记录下各工具的使用心得,以及重点介绍我在工作中是如何使用Jmeter做测试的,都是在windows操作系统下进行。

最开始使用postman,该工具的优点是可以保存测试过程中使用的请求数据,可以把被测系统中所有的接口请求都保存在该工具中,对于排查定位问题,该工具还是很好用的,缺点就是效率太低,碰到一个业务流程涉及执行多个接口时,手动填参数实在慢。

一、安装Jmeter

1.JAVA环境

JDK下载地址http://java.sun.com/javase/downloads/index.jsp 

配置系统变量:

(1)JAVA_HOME,变量值为:你在本地安装JDK的目录。

   C:\Program Files\Java\jdk1.6.0_10;

(2)CLASSPATH,变量值为:

    C:\Program Files\Java\jdk1.6.0_10\lib\dt.JAR; C:\Program Files\Java\jdk1.6.0_10\lib\TOOLS.JAR; C:\Program Files\Java\jdk1.6.0_10\BIN;

(3)修改PATH变量

   添加C:\Program Files\Java\jdk1.6.0_10\bin;

检测JDK安装是否成功:运行-->CMD-->输入"java",如果能看到帮助信息说明JDK安装成功。

2.JMETER环境

下载地址:http://jmeter.apache.org/download_jmeter.cgi

解压apache-jmeter-2.11.zip到本地(任何目录均可),比如我把它下载到:“E:\Jmeter\apache-jmeter-2.3.4”。

配置系统变量:

(1)JMETER_HOME,变量值为:

  E:\Jmeter\apache-jmeter-2.3.4

(2)修改CLASSPATH变量

   添加%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar;% JMETER_HOME%\lib\jorphan.jar;%JMETER_HOME%\lib\logkit-1.2.jar; 

JMeter插件安装

1. 插件下载地址: http://jmeter-plugins.org/downloads/all/

2. 插件下载后解压:找到JMeterPlugins-Extras.jar,把JMeterPlugins-Extras.jar放到apache-jmeter-2.12\lib\ext目录。

运行方式:点击Jmeter目录下bin文件夹里的jmeter.bat就可以打开Jmeter。

 

二、运行一个HTTP请求

1.添加一个线程组

线程属性{Ramp-Up Period(in seconds)}:意味着这个线程内的所有线程(对我来说是http请求)在多久时间内执行完毕,值为0,意味着并发执行线程组下的所有请求。

2.添加一个HTTP请求

“线程组”右键->添加->Sampler->HTTP请求

3.添加“察看结果树”

 “线程组”右键->添加->监听器->查看结果树

4.运行

 

二:GET/POST请求参数填写

举例来说

我的被测系统API的http请求涉及到GET/POST/PUT/DELETE四种。请求传参可分为两种:

GET请求

1
http: //请求路径/Ecs-duHc0U4E  #该请求参数“Ecs-duHc0U4”以斜杠形式传入

POST请求 

1
http: //请求路径?subnetCode=Subnet-tQSPwlp1&imageCode=image-djcgebxfd  #该请求参数subnetCode和imageCode以问号形式传入

区别是:
第一种解析的时候会把后面的字符当做路径或是地址;

第二种解析的时候会把后面的地址当做匹配关键字,“?”起连接作用,表示要带参数,“&”作为不同参数的间隔符。

 

Jmeter中的请求方式

1、GET请求

  

在察看结果树中看到完整的请求路径是:http://10.10.28.131:8080/middleware/v2/ecs/Ecs-do93KwLL

2、POST请求


在察看结果树中看到完整的请求路径是:http://10.10.28.131:8080/middleware/v2/ecs/power/stop?ecsCode=Ecs-AwDrEYdx

三:管理请求服务器信息和Headers参数

如果使用Jmeter同时执行多个http请求任务,就需要创建多个HTTP取样器,每一个取样器都来手动填写服务器信息和端口号,会非常消耗时间。

解决方法:Jmeter之HTTP请求默认值

1、添加方式

“线程”右键->添加->配置元件->选中HTTP请求默认值

2、配置好服务器IP和端口以后,新建一个HTTP取样器,不填写服务器信息。

3、运行,检查结果。

可以看出该配置元件是作用于整个线程内的,对该线程内的所有HTTP请求都生效。

 参数列表:

AttributeDescriptionRequired
Name
组件名No
Server
域名或IPNo
Port端口No
Connect Timeout连接超时时间(单位毫秒)No
Response Timeout响应超时时间(单位毫秒)No
Implementation实现方式,默认值为Jmeter属性:jemter.httpsamplerNo
Protocol协议,HTTP or HTTPSNo
Method请求方法:HTTP GET or HTTP POSTNo
Path请求资源路径No
Send Parameters With the Request参数列表No
Server (proxy)代理服务器的域名或IPNo
Port代理服务器的端口No, unless proxy hostname is specified
Username代理服务器的用户名No
Password代理服务器的密码No
Retrieve All Embedded Resources from HTML Files告诉Jmeter解析HTML文件并发送所有资源请求(包括图片,java小程序,JS,CSS等)No
Use concurrent pool用一个连接池来获取嵌入的资源No
Size用于获取嵌入式资源的并发连接池大小No
Embedded URLs must match:URL匹配,过滤No

 

我的被测系统中Headers需要填写参数,该参数作为用户唯一标识符,请求传入了它服务器才会对请求作出响应。

Jmeter之HTTP信息头管理器

1、添加方式

“线程”右键->添加->配置元件->选中HTTP信息头管理器

2、运行一个请求,查看请求数据

可以看出请求中的headers已经传入我所填写的参数accessKey,并且该配置元件同样作用于该线程内所有请求。


四:响应断言

Jmeter中断言的类型有许多,我不在这里一一列举,只说下我用到的---响应断言。

作用:一个HTTP请求发出去,怎么判断执行的任务是否成功呢?通过检查服务器响应数据,是否返回预期想要的数据,如果是,判断任务成功,反之任务失败。

1、添加方式

选中一个取样器,右键->添加->断言->选中“响应断言”

(1)Apply to

关于应用范围,我们大多数勾选“main sample only” 就足够了,因为我们一个请求,实质上只有一个请求。但是当我们发一个请求时,可以触发多个服务器请求,就有main sample  和 sub-sample之分了。

(2)要测试的响应字段

勾选“响应文本”,会在响应数据中进行校验。

(3)匹配规则

勾选“包括”,意味着只要相应数据中包含要校验的字段,任务就算成功。

(4)要测试的模式

即需要校验的数据值。

2、查看运行结果

(1)失败的任务

判断为任务失败,查看结果树任务结果颜色标红。

(2)成功的任务

判断为任务成功,查看结果树任务结果颜色标绿。


五:正则表达式提取器

(正则表达式提取器是Jmeter关联中的一种)使用场景:

有两个HTTP请求,请求A的返回数据中有一个字段“ABCD”,该字段要作为请求B的入参。

1、添加方式

请求A上右键-->后置处理器->正则表达式提取器

2、提取A请求中的taskCode对应的值

为了获取到上图中圈起来的这个值,要配置正则表达式提取器:

说明:

(1)引用名称:下一个请求要引用的参数名称,如填写Atask,则可用${Atask}引用它。

(2)正则表达式:

    ():括起来的部分就是要提取的。

    .:匹配任何字符串。
    +:一次或多次。
    ?:不要太贪婪,在找到第一个匹配项后停止。

(3)模板:用$$引用起来,如果在正则表达式中有多个正则表达式,则可以是$2$$3$等等,表示解析到的第几个值给title。如:$1$表示解析到的第1个值

(4)匹配数字:0代表随机取值,1代表全部取值,通常情况下填0

(5)缺省值:如果参数没有取得到值,那默认给一个值让它取,我填的Error。

 3、获取到的值传入B请求

看一下请求B是否如预期的一样传入Atask这个值

引用成功~~

 

记录一个好用的测试正则表达式的工具:

工具名称:RegexTester

使用方法:

 

六:从文本读取参数

使用场景:测试一个接口并发处理数据的能力,并且每次请求传入的参数都要不同。

解决方法--- CSV Data Set Config 

列举一个实例,步骤中会侧重读取参数操作的说明,其他有疑问的步骤请查阅博主之前Jmeter相关的文章。

1、创建HTTP请求默认值---为了指定请求的服务器信息

2、创建HTTP信息头管理器---为了在Headers中传值

3、创建HTTP采样器---我们的请求任务

填好Http请求方式和请求路径,请求参数用变量方式引用进来,变量来源于CSV Data Set Config配置:

(1)添加CSV Data Set Config

(2)配置CSV Data Set Config

  • Filename:需要传入的参数所位于的文件名称,一定要填写完整路径,博主填写的绝对路径。
  • File encoding:参数文件的编码格式。可以不填。
  • Variable Names:对应参数文件中每列的变量名,也是你要引用到请求中的参数变量名。例如博主填写的值为ecsCode,在http请求中引用该参数时${ecsCode}
  • Delimiter:文件中的分隔符,一般用英文的逗号分隔开即可。
  • Allow quoted data?:是否允许引用数据。博主没有用到,默认设置为 false。
  • Recycle on EOF?:是否循环读取参数文件内容。设置为 true 时,意味着已经读取完参数文件内的测试用例数据时,线程循环次数仍然没有结束,那就循环读取参数文件数据;设置为 false 时,若已至文件末尾,则不再继续读取测试数据。
  • Sotp thread on EOF?:当读取到参数文件末尾时,是否停止读取线程。默认为 false。当 Recycle on EOF?  设置为 true 时,此项不起任何作用。当且仅当 Recycle on EOF? 为 false 时,此项配置才生效。
  • Sharing mode:共享模式,即参数文件变量作用域,博主没用到就不关注他。

(3)在文本中填写参数

  • 该文件所在的路径即为CSV Data Set Config配置元件中的Filename值;
  • 博主只传入一个参数,所以只有一列,如果有两个参数,会有两列数据,并用英文逗号隔开;引用参数时,CSV Data Set Config配置元件中Variable Names填写两个变量,也用英文逗号隔开即可
  • 有10行数据,意味着10条测试用例,我会设置线程循环10次。这也是为什么我会在CSV Data Set Config配置元件中Recycle on EOF填写False

循环次数设置为10,意味着该条请求只执行10次。

Ramp-Up Period设置为0,意味着10条请求同时发出。如果设置为5,意味着5秒内发起10条请求,平均1秒发出2条。

(4)在请求中引用参数

4、增加一个响应断言,意味着返回数据包含“执行成功”字样,任务成功

5、添加监听器-察看结果树

测试得知,按照预期取到了值~

七:用户定义的变量

使用场景:一组API根据业务流程制作成测试脚本,想要移植到其他测试环境时,由于数据库发生了变更,有些初始化数据也相应发生了变化,例如环境地址、请求路径等等。博主甚至把服务器地址和接口的部分共同请求路径都做成了自定义变量。

 

1、添加方式
线程组 右键->添加->配置元件->用户定义的变量

 

2、作用范围

当前的线程组内所有取样器(即博主的HTTP请求)都可以引用变量

3、变量引用方式

 

需要说明的是,服务器IP地址和端口号以及接口共同的请求路径部分,作为变量引用时,需要在路径填充表格的最前面添加两个斜杠“//”,不加的话会引用失败。

八:模拟OAuth2.0协议简化模式的请求

背景

       博主的主要工作是测试API,目前已经用Jmeter+Jenkins实现了项目中的接口自动化测试流程。但是马上要接手的项目,API应用的是OAuth2.0协议授权,并且采用的是简化模式(implicit grant type)。所以最近学习了一下该协议,并尝试用Jmeter模拟该授权方式的处理流程,以改进自动化测试脚本。

   本文主要分为三个部分:1、简述OAuth2.0协议中的简化模式授权方式;

              2、通过在浏览器上抓包,分析获取授权的过程中经历了什么;

              3、尝试用Jmeter模拟整个授权过程,获取授权令牌。

 

一、OAuth2.0协议简述

OAuth 2.0定义了四种授权方式。博主这里只介绍简化模式。有兴趣了解该协议全部内容的同学可以参考本文末的参考文章。

授权过程中参与的四种角色:

  • 资源所有者(Resource Owner):对资源具有授权能力的人。即用户。
  • 第三方应用(Client):获得资源所有者的授权后,就可以去访问资源所有者的资源。
  • 资源服务器(Resource Server):存储资源,并处理对资源的访问请求。
  • 授权服务器(Authorization Server):它认证资源所有者的身份,为资源所有者提供授权审批流程,并最终颁发授权令牌(Access Token)。

请注意,为了便于协议的描述,这里只是在逻辑上把授权服务器与资源服务器区分开来;在物理上,AS与RS的功能可以由同一个服务器来提供服务。

 

简化模式的基本工作流程如下:用户被请求授权应用程序,然后授权服务器将访问令牌传递回用户代理,用户代理将其传递给应用程序。

Step 1: Implicit Authorization Link

使用简化模式授权类型,用户会得到一个授权链接,它会从API来请求获取令牌(即:token)。授权链接如下所示:

http://10.10.28.141:9999/uaa/oauth/authorize?response_type=token&client_id=cmop&redirect_uri=http://example.com

对授权链接的各部分介绍:

  • http://10.10.28.141:9999/uaa/oauth/authorize:API授权端点
  • client_id=cmop:应用程序的客户端ID(API用来标识应用程序)
  • redirect_uri=http://example.com:当令牌颁发之后,认证服务器把用户导向客户端指定的重定向URI
  • response_type=token:表示授权类型,固定值为token,表示请求授权令牌

Step 2: User Authorizes Application

当用户点击这个链接时,首先要登录到服务器验证身份(除非已经登录过),然后服务器会提示用户进行授权或拒绝第三方应用使用他们的账户。

Step 3: User-agent Receives Access Token with Redirect URI

如果用户同意授权,授权服务器将用户导向客户端指定的“重定向URI”,并在其中携带一个包含访问令牌的URI片段,看起来像这样:

http://example.com/#access_token=b8c512ef-8083-4654-b71b-7bbe85b03d8d&token_type=bearer&expires_in=19062&scope=open

对重定向URI的各部分介绍:

  • access_token:表示访问令牌
  • token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型
  • expires_in:表示过期时间,单位为秒
  • scope:表示权限范围

 

好了,后面提取令牌以及把令牌发回给应用程序的步骤就不展开了,我们只要了解到如何获取到授权令牌就可以了,接下来访问服务器资源的时候,在请求API的requests中带入令牌参数即可。

 

二、浏览器抓包过程

 1、在浏览器中使用授权链接发起申请令牌请求

http://10.10.28.141:9999/uaa/oauth/authorize?response_type=token&client_id=cmop&redirect_uri=http://example.com

  (1)Firefox浏览器,打开Firebug,输入授权链接发起请求,如下图:

     从图上可看出,我发起请求后,抓到6条GET请求,前两条是我们需要关注分析的数据,后面四条都是在请求页面元素所以不做关注:

      • 第一条请求:GET请求授权链接,返回状态码为302,表示请求链接被暂时性重定向;
      • 第二条请求:GET请求暂时性重定向的链接,即跳转到目前的页面,其URL为http://10.10.28.141:9999/uaa/login.html

    (2)接下来我们看一下前两条requests中的具体信息,如下图:

 

        从图上可以看出,发起第一个GET请求(即授权链接),在其响应头信息(Response Headers)中的Location字段标明了接下来浏览器将重定向的地址;而且还在其中返回一个Set-Cookie字段;

        再来看第二个请求,他的请求头信息(Request Headers)中包含一个参数Cookie,该值与上面的Set-Cookie字段的值相同。

  注意:我们把这里的Set-Cookie和Cookie的值起个名字,叫做JSESSIONID_1,方便和后面的cookie值进行区分。

2、用户同意进行授权操作 

http://10.10.28.141:9999/uaa/login.html

  (1)在前一步的操作中,我们进行到浏览器跳转到暂时性重定向的页面,等待用户输入账号密码验证身份,然后进行授权。

    我们首先输入正确的用户名密码,通过验证,查看浏览器会发出什么请求:

 

     从图上可看出,我在输入用户名密码后,抓到3条请求,并且浏览器跳转到指定的重定向URI,而且可以在该链接中看到服务器返回来的access_token参数:

      • 第一条请求:POST请求,向服务器提供用户名密码参数,服务器验证用户身份通过后,跳转回申请授权链接;
      • 第二条请求:GET请求,再次向服务器请求申请授权令牌(此时已经得到用户的授权),服务器会颁发令牌,认证服务器把用户导向客户端指定的重定向URI;
      • 第三条请求:GET请求,重定向的URI,并且其中包括访问令牌access_token

(2)接下来我们看一下request中的具体信息:

      • POST请求:请求头信息中传入的cookie参数,与第一个步骤中获取的JSESSIONID_1值一模一样。响应头信息中返回的Set-Cookie值记录为JSESSIONID_2;
      • 第一个GET请求:再次跳转到授权链接向服务器发起请求,此时请求头信息中传入的Cookie参数是JSESSIONID_2,响应头信息中的Location字段包含令牌;
      • 第二个GET请求:我没有截他的图,因为他只是最终认证服务器把用户导向的重定向URI。而我们已经拿到token的数据了。

 

总结:从用户在浏览器输入授权链接到最后浏览器返回给我们access_token的过程中,由于其中包含暂时性重定向的地址,所以浏览器自动进行过很多跳转。需要我注意的只有两个请求,第一个是GET请求授权链接,浏览器会自动跳转到用户身份验证页面,并保存一个cookie(我叫它验证cookie);第二个就是POST请求用户认证连接,传入用户名和密码参数,并带入验证cookie,服务器验证用户身份后再返回另一个cookie(我叫它授权cookie),也保存在浏览器中,然后自动跳转到授权链接,此时传入授权cookie,服务器即颁发正确的令牌给用户~~

 

三、Jmeter模拟获取令牌

通过前两部分的分析,我需要发送两个请求即可。

GET http://10.10.28.141:9999/uaa/oauth/authorize?response_type=token&client_id=cmop&redirect_uri=http://example.com
POST  http://10.10.28.141:9999/uaa/login.html

请求一:

请求二:

 

执行测试:

结果里面会发现,第一个请求执行没问题。但是第二个请求最后没有重新跳转回授权链接,更别提Response headers里面会有服务器颁发的令牌了!!

问题肯定是出在第一个GET请求的cookie没有传入POST请求,我翻了翻Jmeter的官方文档试图找到什么方法能够传递cookie这个参数,很快我就找到一个跟cookie相关的配置元件----前方高能预警!!!!!

HTTP Cookie Manager(HTTP Cookie管理器)

长话短说,我把这部分的重点直接从官网翻译过来如下:

——cookie管理器主要有两个功能

  • 它可以像浏览器一样保存并发送cookies:如果你的http请求的响应中包含一个cookie,那么Cookie Manager就会自动保存这些Cookie并在所有后续请求该站点的请求中使用这个Cookie的值。对Jmeter来说,每个线程都有自己的“cookie存储区域”。(注意:这样的cookie不会在Cookie Manager中展示给用户,但是用户可以使用监听器“查看结果树”来查看)
  • 用户可以手动添加cookie到Cookie Manager,这种方式添加的cookie会被Jmeter的所有线程共享。

从上面这段话可以得出,我的需求是第一种~也就是只需要在线程内添加一个Cookie Manager配置元件即可。

1、添加HTTP Cookie 管理器

2、执行测试

 

bingo~~~~~~~

access_token所在的URI正确获取到,POST请求中也传入了cookie.

 

注:如果在查看结果树中没有看到cookie的值,请检查Jmeter的/bin目录下jmeter.properties文件中CookieManager.save.cookies的值是否设置为true

 

 

参考资料:

OAuth2.0

http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

 

Jmeter

http://jmeter.apache.org/usermanual/component_reference.html#HTTP_Cookie_Manager


九:跨线程组传递变量

使用场景:

请求API需要授权令牌,但是授权令牌只需要获取一次,即可调用服务器上其他业务接口。

所以我想要把授权操作放在单独的一个线程,业务流放在其他线程。

这就需要我把从授权线程获取的令牌传入业务流线程。

 

解决方法———后置处理器Beanshell PostProcessor

1、首先选择“获取token”线程组:添加正则表达式,提取出token的值(不会使用正则表达式的同学请查阅博主之前Jmeter相关文章)

2、在“获取token”线程组:添加后置处理器BeanShell PostProcessor

Parameters:引用正则表达式提取的变量${token}

Script:具体beanshell语法大家可去查看相关资料,这里很简单,一条语句就搞定。

    意思是把获取的变量${token}设置为全局变量,并以新的名字newtoken来进行引用。

3、在“业务流”线程组引用全局变量newtoken

引用方式是${__P(newtoken,)},注意花括号中是两个下划线,newtoken后还跟一个逗号,不要写漏了。

 

至于我在这个线程组里面加的固定定时器,是因为如果不加定时器,两个线程是同步执行的,会发生token值还没有获取到就进行业务流的接口请求,造成请求返回失败。

4、执行,查看结果

获取到的token值为上图所示

引用成功~


转自:http://www.cnblogs.com/LiangHu/tag/Jmeter/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值