如何用jmeter做接口测试
目录
4.3.8 Pre/Post Processor(前置/后置处理器)
1 前言
你是不是刚刚脱离手工测试的苦海,又走进写go语言自动化用例的另一片苦海?是否对代码中高度重复性的工作感到心累?如果是,那么,你的福利来了~~~
本文应用JMeter的背景是:PaaS 1.2开放K8S原生API,针对开放的90+原生接口,开始遍历各种场景写自动化用例,首先自动化用例不能嵌套太深,其次,在低耦合的情况下,代码冗余很严重(我们做的可是接口参数校验啊),每一个测试点的差异都是一个冗长的测试用例。后来在夏老师的指导下,开始使用JMeter对接口进行定义,调试方便,结果直观,运行只在秒级,尤其在检视《API 接口》文档时发挥了无与伦比的优势。这样的神器,你值得掌握~~~
由于小女子也才接触不多时日,本文旨在给想要使用JMeter进行接口测试的童鞋提供一点点帮助,想要更深入的了解JMeter的功能,也可以咨询夏老师~~~如果有哪些改进建议,也欢迎与我联系,如果想获得本文的示例代码,那就只能与我联系了,我不会告诉你,已经更新到SVN上了,地址为:http://hghsvn04-rd:6801/svn/CRDU_PaaS_V100R002_SVN/DOC/04.Test/99 测试交流/CCE服务/OpenAPI/测试设计/验收用例
2 什么是JMeter?
Apache JMeter是Apache组织开发的基于Java的压力测试工具。其原本的目的是提供一款易用且功能强大的Web服务器性能测试工具,但随着不断的发展,JMeter已经可以完成很多的性能测试场景,其支持的协议包括:FTP, HTTP, JDBC, SOAP, LDAP, SMTP等等。
3 安装JMeter
3.1 下载安装包
下载地址:http://jmeter.apache.org/
Step 1:
Step 2:
Step 3:
Step 4:用户可以根据需要下载JMeter的版本。本文写作时所用版本为JMeter 3.0。
3.2 安装软件
JMeter本身并不需要安装,下载后解压到本地即可,但需要有Java环境的支持,在JMeter的主页已经说明清楚,并对Java版本有具体要求。
3.3 启动JMeter
在解压后的JMeter目录有一个bin子目录,进入bin子目录后双击jmeter.bat即可启动JMeter。启动JMeter时,会弹出一个Dos窗口,如果关闭该窗口,则JMeter自身也会关闭。
可以写一个vbs脚本启动JMeter而不必弹出Dos窗口。脚本内容如下:
Dim wsh Set wsh=WScript.CreateObject("WScript.Shell") wsh.run "jmeter.bat",0 |
将以上脚本保存为JMeter.vbs并存放到JMeter的bin目录,再双击JMeter.vbs即可运行JMeter且不弹出Dos窗口。
4 使用指南
4.1 主界面
Jmeter的主界面比较简洁,分为工具栏,工程窗口和属性窗口。当选中工程窗口中的节点时,属性窗口会显示相关的属性。
4.2 工具栏
(1)----打开已有的工程;
(2)----选中/去选中某个已选中的用例,灰色表示这个下面的所有用例均不会被选中参与用例执行;
(3)----运行测试任务;
(4)---停止测试任务;
(5)----清除历史结果;前一个按钮只会清除选中的Listener的结果, 后一个按钮会清除所有的结果;
(6)----获取联机帮助:在工程窗口选中样本,在工具栏上点击帮助按钮,会弹出如下的帮助窗口;
(7)----调试窗口
4.3 工程窗口
4.3.1 创建新工程
点击工具栏第一个按钮可以新建一个工程。新工程分为两个节点:Test Plan(测试计划),WorkBench(工作台),Test Plan中的任务就是整个测试工程的核心,在其中会创建线程组,配置元件,样本等等。
在测试计划中选中“Run Thread Groups consecutively”(独立运行每个线程组),则可以设置线程组顺序执行。如果Test Plan下有多个Thread Group,则会按前后顺序等前一个线程组执行完成后,后面的线程组才会执行。如果不选中“Run Thread Groups consecutively”,则所有活动的线程组将会并发执行。
测试计划是使用JMeter进行测试的起点,它是其他JMeter测试元件的容器。下面介绍JMeter使用的主要元件。
4.3.2 Thread Group(线程组)
线程组就是测试任务,可以指定该任务执行多少次,是否自动停止等。一个Test Plan可以添加多个线程组,相当于多个测试任务,多个测试任务可以并行执行,也可以顺序执行。
线程组代表一定数量的并发用户,它可以用来模拟并发用户发送请求。实际的请求内容在Sampler中定义,Sampler被线程组包含。
添加线程组
在Test Plan上单击右键,选择“Add => Threads(Users) => Thread Group”。
线程组类型
① Setup Thread Group
该种类型的线程组相当于一个预处理线程组,其任务会在Thread Group线程组前执行,可以用于设置一些预置条件。
② Teardown Thread Group
Teardown Thread Group刚好和setUp Thread Group作用相反,它用于执行后置条件,可以用于测试任务完成后进行环境恢复等运作。
③ Thread Group
使用最多的就是这种类型的线程组,该线程组就是测试任务的载体。
线程组配置
① Number of Threads
用于配置线程数的个数,线程数越多,发送的消息量也越大。
② Ramp-Up Period
可以理解为爬坡时间,该时间是指从任务启动开始,到创建完所有的线程。比如100个线程,所需要的时间。如果Ramp-Up Period设置为10,而Number of Threads设置为100, 则表示这个100个线程,要花费10秒,平均每秒会启动10个线程。
③ Loop Count
表示线程循环执行多少次,如果是进行调试测试工程,一般都会先设置成1次。而到正式执行压力测试时,会设置成“Forever”,即待久执行,由用户手工停止。
4.3.3 Test Fragment(测试片段)
测试片段是控制器上的一个种特殊的线程组,它在测试树上与线程组处于一个层级。它与线程组有所不同,因为它不被执行,除非它是一个模块控制器或者是被控制器所引用时才会被执行。为了在调试过程中可以随意指定执行哪个测试用例,所以本文将所有的组件都设置成了Test Fragment。
4.3.4 Listerner(监听器)
Jmeter中通过监视元件(Listener)来观察样本发送的消息的状态。常用的监视元件有:View Results Tree和Summary Report。
添加监听元件
(2)View Results Tree(察看结果树)
该监视元件会将样本发送的每条消息的请求和响应都详细的记录下来,方便进行调试,可以协助测试人员在测试工程制作阶段排除问题。
(3)Summary Report(聚合报告)
该监视元件不会记录详细的请求和响应报文,而只是记录各个样本请求和响应的次数,成功率及时间指标等信息,该监视元件对于系统的评价实测系统的各项指标能提供直观的数据。
各个标题的意义如下:
Label: 样本的名称,如果工程中使用了多个样本,可以通过label进行区分;
Samples: 总计发送的消息数
Average: 消息的平均时延, 单位是ms
Median:中位数,也就是 50% 用户的响应时间
90% Line:90% 用户的响应时间
Min: 消息的最小时延: 单位是ms
Max: 消息的最大时延: 单位ms
Error: 失败比例
Throughput: 吞吐量,可以理解为TPS,即每秒发送的消息个数
KB/Sec: 每秒发送的数据量
4.3.5 Config Element(配置元件)
配置元件(Config Element)相当于协议管理器,主要用来管理协议连接,用的最多的主要是一些协议的默认请求模板。比如要测试HTTP协议,就会用到HTTP类型的配置元件。需要注意的是,配置元件并不是消息驱动器,而只是协议管理器,只添加配置元件,并不能发送消息。
(1)添加配置元件
添加配置元件通过线程节点,或者在Test Plan节点上单击右键,选择“Add => Config Element => HTTP Request Defaults”,如下图所示:
(2)配置元件作用范围
配置元件对同级别的后续节点生效,对子节点生效。配置元件并不是必须的,可以直接添加样本元件,并进行相关协议接口的配置。
(3)添加变量
使用变量的一个好处是可以通过一处修改,所有引用该变量的元件都会相应修改。在测试计划中添加的变量,在整个工程中都可以使用。如下图所示:
使用“User Defined Variables”配置元件来定义变量,比在测试计划节点定义变量更灵活,用户变量配置元件可以添加到不同的节点下,用来限制其作用范围。
4.3.6 Sampler(取样器)
Config Element相对来说是一个静态的配置器,其并不会发送或者接收消息,而只会对同类型的样本提供配置参考,如果样本没有配置服务器,而配置元件中配置了服务器信息,则样本参照配置元件中的服务器配置信息进行链路建立及消息收发。
样本是真正的执行器,因此对一个工程来说,样本是不可少的。
添加样本:样本的类型决定了测试接口的类型
Debug Sampler
一般而言,View Results Tree就能满足我们简单调试工程的需要,但对于复杂的工程,特别是参数引用及变量引用非常多时,可能会出现要跟踪各种变量的情况,Jmeter提供了一个元件叫Debug Sampler,该样本可以在View Results Tree中显示,并把所有的变量结果打印出来。可以添加多个Debug Sampler在不同的样本后面, 这样, 每个样本执行后的变量的状态都可以进行跟踪。
4.3.7 Logic Controller(逻辑控制器)
逻辑控制器可以自定义JMeter发送请求的行为逻辑,它与Sampler结合使用可以模拟复杂的请求序列。Logic Controller类似于编程语言中的for循环那样的控制结构,它可以控制树形结构下面包含的Samplers的执行方式。
添加Logic Controller
(2)逻辑控制器类型
①仅一次控制器
例如我们需要进行一次用户登陆操作,每一个用户(Thread)都需要单独login,但是在一个用户的所有HTTP requests中(即一个session)只需要login一次。因此如果可以将这个Sampler放到Once Only Controller下面,即可保证login只在一个session中执行一次。
②简单控制器
本文在K8S接口测试中,定义了大量的简单控制器,其功能类似于Ginkgo中的Context,给用例添加说明,方便区分不同的用例级别。K8S的所有接口都定义在了简单控制器中。
③模块控制器
本文在K8S接口测试中,同样使用了大量的模块控制器。前文提到,为了方便调试,把可以定义线程组的地方定义成了Test Fragment,因此,执行这些Test Fragment就需要模块控制器。如下图,点击模块控制器,可以选择执行哪个定义的组件。
4.3.8 Pre/Post Processor(前置/后置处理器)
前置/后置处理器负责在生成请求之前和之后完成工作。前置处理器常常用来修改请求的设置,后置处理器则常常用来处理响应的数据。比如Pre-processor(预处理器)可以在Sampler向Server发送请求之前定义一些变量或做处理;而Post-Processor可以在得到Response之后作一些操作。
4.3.9 Timer(定时器)
定时器负责定义请求之间的延迟间隔。例如需要在两个HTTP请求之间延时一个时间段,可以加上定时器,这样不至于给服务器造成过多的影响。
5 API接口示例详解
5.1 总览
整个K8S接口测试的工程结构如上图所示。
5.1.1 设置监听器
本工程共设置了两个监听器:察看结果树和聚合报告,用于查看每次测试用例执行的情况。
5.1.2 设置变量
为了展示方便,本文针对PaaS 1.2开放的API接口各个组件的变量分别进行了定义:
k8s相关变量
该节点定义了整个工程公共的变量,主要包括api gateway的ip和port,iam的ip和port以及测试过程中应用到的镜像。
组件相关变量
K8S开放的API接口主要概括为8部分:Cluster(自研)、RC、Service、Pod、Secret、Namespace、PodTemplate以及Endpoint。为了方便查看、修改,针对每个接口分别设置了一个变量模块,定义的内容主要是接口中会引用到的name、labels等信息。以RC为例如下所示:
5.1.3 设置线程组
本工程共设置了两个线程组:
SetUp Thread Group
该线程组的任务会在Thread Group线程组前执行,可以用于设置一些预置条件。这里设置的预置条件包括获取token,获取集群Clusteruuid,作为其他组件执行前的头域。且将其设置为仅一次控制器,这样在执行线程组时,只需要执行一次获取token操作,不需要重复获取。
①获取token:按照具体的用户名、密码等获取token;
②获取token变量:这里添加了一个后置处理器来获取token变量保存token值,方便后续引用;
③获取集群clustername、clusteruuid
④设置全局属性:将token、clustername、clusteruuid通过函数设置为全局变量;
Thread Group线程组(命名为“单用例执行”):该部分是整个工程执行的入口;
①HTTP信息头管理器:定义了用例的执行需要携带的头域信息。
②RUN:这是一个模块控制器,在这里可以选择要执行的用例。
5.1.4 设置Test Fragment
上文提到过,Test Fragment和线程组的区别是Test Fragment不被执行,但可以被模块控制器执行。因此,这里将K8S开放的API接口以组件为单位进行了定义,以RC为例,如下图所示:
(1)每一个接口定义为一个简单控制器,没有特殊的功能,主要是定义一些描述信息(暂时这么理解),由于没有统一的写作规范,所以定义的接口可能给读者阅读带来不便,简单说明如下:
Create:创建一个RC;
Delete:删除指定的RC;
……
(2)添加Sample:HTTP请求,这是接口的核心部分,定义了请求的URL及body体。有了这部分,就可以发送请求了。
Test Fragment的模块控制器
如上图所示,RC组件中的Replace接口有一个Read的模块控制器,像链接一样连接到了其他接口。没错,这就是模块控制器与简单控制器的区别,在执行RC组件的Replace接口之前,需要先获取接口信息,如果再重新定义一个Read接口,显然是多余的,因此就可以添加一个模块控制器,直接点击其要“链接”的接口就可以获取接口信息了,是不是很方便呢?
5.2 单个用例执行
至此,JMeter的关键元件就介绍完了,定义的接口各部分也作了说明,下面就执行一个完整的K8S用例看一下吧。还是以RC为例,执行以下用例(各组件均已提前定义好名称):
创建Namespace
接口定义:
用例执行
查看结果:
清理数据:
创建RCà更新RCà列举RCà删除RCà删除Namespace:同样的方法执行这些操作,可以在结果树中查看每一步的执行情况;
5.3 用例连跑
这样执行用例怎么行呢,有100个用例我不是很心累嘛~~嗯,也许你已经想到解决办法了,没错,当然就是使用模块控制器啦,想怎么安排用例就怎么安排用例。
创建一个Test Fragment,命名为“RC的一系列操作”;
再创建一系列模块控制器,“链接”到某个接口,如下图:
执行测试用例时,只需要选中“RC的一系列操作”,就可以将该Test Fragment下的所有用例运行起来了;
察看一下运行结果
所有的用例都一次性执行,并且可以看到,与之前执行结果不同的是,SetUp Thread Group中定义的内容只执行一次,为什么?翻翻前面的内容就知道了~~~
5.4 结果展示
今天发现了一个不错的功能,如图:
默认情况下,察看结果树为“Test”类型,响应的body体堆叠不能清晰识别,或者还要找一个Josn的解析器来帮我们分析一下响应body体。然而察看结果树的展示类型是可选择的,如下图:
选择显示的类型为“Json”结构,Jmeter就可以轻松帮我们呈现结构清晰的响应body体。
6 改进
(1)在测试过程中,测试人员都是根据自己的使用习惯进行各个节点的定义、引用,没有统一的规范,维护需要一定的成本,如果推广JMeter的使用,应该定义一个统一的规范。
- 点赞
- 收藏
- 关注作者
评论(0)