一、线程组
线程组元件是任何一个测试计划的开始点。在一个测试计划中的所有元件都必须在某个线程组下。所有的任务都是基于线程组:
通俗理解:
· 线程组:就是一个线程组,里面有若干个请求;
· 线程:一个线程就是一个“虚拟用户”;
· 请求:一个线程组里面有若干个请求。
对应关系:
例如:1个线程组里面有10个请求,线程数为10个,跑完后得到:
理解为:(10个线程数)10个人,每个人都要跑这10个请求,所以:10*10=100:
并发数:100;线程数:10;
PS:线程组也可以看作是一个虚拟用户组。线程组中的每一个线程都可以理解为一个虚拟用户。
二、线程组设置:
我们把线程组的设置分成3个区域:
区域一:在采样器失败后怎么处理(LoadRunner里面也有类似的运行设置选项,对比去学习):
1、continue:继续执行接下来的操作;
2、Start Next Thread Loop:开始下一次循环;
3、stop Thread:停止线程,退出该线程(不再执行此线程的操作);
4、stop Test:等待当前执行的采样器结束后,结束整个测试;
5、Stop Test Now:马上停止测试;
区域二:线程属性:
1、Number of Threads(users):线程数,相当于模拟的用户数量;
2、Ramp-up Period(in seconds):达到指定线程需要的时间,例如线程数为100,时间设定为10s,那么就是10s加载 100个线程,每秒启动的线程数=100/10=10;
3、Loop Count:如果填具体的数值,就是循环对应的次数;如果选择“Forever”,则一直执行下去,直到手动停止;
4、Delay Thread creation until needed:延迟线程创建,直到需要才创建。
区域三:调度器配置:
需要选中调度器(scheduler),调度器配置才生效。
【实例】现用一个普通的线程组测试一个简单的http接口测试,测试前添加设置下线程组及其他元件:
第一步:添加一个线程组,添加后选择采样器因接口、报文或外部等原因导致接口执行错误后的一个后置行为,对于各个选项多选一,目前我选择接口执行错误后让其继续执行。
第二步:因为非性能测试所以线程组设置1即可,即是单个“虚拟用户”。
第三步:关于调度器配置不同版本的Jmeter会有不同的改动,目前Jmeter版本V5.1.1调度器配置在原有的基础上容易理解和执行,使用调度器器之前需“开启”调取度按钮(点击打勾即可),按照功能提示选择接口的启动延迟时间和持续时间。注意:使用调度器后中间循环次数则作废。
第四步:添加http请求并设置域名、路径等并填入请求报文;(添加路径:线程组→添加→取样器→HTTP请求)
第五步:添加HTTP信息头管理器,用于存储request的head部分,并写入对应接口的request的head部分:(添加路劲:线程组→添加→配置原件→HTTP信息头管理器)
最后就可以添加察看结果树,然后点击运行就可以看到结果了!(添加路径:线程组→添加→监听器→察看结果树)
三、线程组分类:
从系统的角度来看,Jmeter的线程组主要分为系统原生线程组和可拓展线程组。原生线程组配合调度器、定时器、前后置处理器和逻辑控制器等等已经可以满足大部分测试的需求,但是若要求多维度来设计用户并发数,原生线程组已经不能满足需求。此时,我们可以新增插件的线程组使其更加强大,可自定义设置多种场景等功能,可以更加接近真实用户的使用场景。
(一)原生线程组
1、thread group(线程组):
这个就是我们通常添加运行的线程。通俗来讲一个线程组,可以看做一个虚拟用户组,线程组中的每个线程都可以理解为一个虚拟用户。上文所介绍使用的例子就是此线程组。
2、setup thread group(设置线程组):
一种特殊类型的ThreadGroup的,可用于执行预测试操作。这些线程的行为完全像一个正常的线程组元件。不同的是,这些类型的线程执行测试前进行定期线程组的执行;类似LoadRunner的init,测试开始时进行初始化的工作。
不同的是执行顺序---它会在普通线程组执行之前被触发。
应用场景举例:
A、测试数据库操作功能时,用于执行打开数据库连接的操作。
B、测试用户购物功能时,用于执行用户的注册、登录等操作。
3、teardown thread group(拆线组):
一种特殊类型的ThreadGroup的,可用于执行测试后动作。这些线程的行为完全像一个正常的线程组元件。不同的是,这些类型的线程执行测试结束后执行定期的线程组;类似LoadRunnner的end,测试结束时进行回收工作。
不同的是执行顺序---它会在普通线程组执行之后被触发。
应用场景举例:
A、测试数据库操作功能时,用于执行关闭数据库连接的操作。
B、测试用户购物功能时,用于执行用户的退出等操作。
(二)可拓展线程组
1、Concurrency Thread Group(递增式并发线程组)
这个可以模仿递增式并发(只能递增不能递减),并可设置递增次数、递增时长、到达目标递增数量保持时长等等:
参数解释:
· Target Concurrency:目标并发(总线程数)
· Ramp Up Time:加速时间(总加速时长)
· Ramp-Up Steps Count:加速步骤计数(总加速/递增次数)
· Hold Target Rate Time:保持目标速率时间(到达总线程数后持续时长)
· Time Unit:时间单位(分钟或者秒)
· Thread Iterations Limit:线程迭代次数限制(循环次数)
· Log Threads Status into File:将线程状态记录到文件中(将线程启动和线程停止事件保存为日志文件);
现设计这样一个场景:
这意味着:
3分钟除以5步,每步0.6分钟;100个用户除以5步,每步20个用户;每0.6分钟将添加20个用户,直到达到100个用户,达到100个线程后,所有这些线程将继续运行,并一起打到服务器6分钟;
2、Stepping Thread Group(逐步线程组)
这个可以模仿递增式并发(不但递增还可以递减),并可设置递增次数、递增启动延迟、递增时长、到达目标递增数量保持时长等等:
参数解释:
1、线程组最大用户数:100个
2、初次加载用户前等待时间:10秒,此时没有用户进入
3、第一次加载用户数:10个用户开始
4和5:每隔10秒加10个用户
6、ramp-up在几秒内启动线程组
7、持续压测60秒,一分钟
8、和9:退用户,每10秒退出10个用户
10、上面各种设置的图形表示
3、bzm - Arrivals Thread Group(bzm-到达线程组)
跟Concurrency Thread Group线程组功能作用大同小异。参数解释:
· Target Rate:目标线程数(总线程数)
· Ramp Up Time:所需多少加载时间(总加速时长)
· Ramp Up Steps Count:所需多少个加载梯次(总递增/加速次数)
· Hold Target Rate Time:持续运行时间(到达总线程数后持续时长)
· Time Unit:可以选择用分钟还是秒来做单位
· Thread lterations Limit:线程迭代次数限制。如果我们只需要运行每个用户一次以模拟用户的实际行为,则可能会很有用。在我们的例子中,该字段为空,因此每个用户将运行不确定的迭代,直到调度结束。
· Log Thread Status into File:将线程状态记录到文件中
· Concurrency Limit:最大并发数限制。以避免出现内存不足的问题。在我们的例子中是1000,这是一个很大的数字。
现设计这样一个场景:
所以以上设置就等于:3min除以5步,等于每步加速后持续0.6分钟,100个用户除以5步,等于每步加速20个用户,达到100个用户后持续跑6mn。
4、Ultimate Thread Group(最终线程组)
这个线程就比较难以理解,但是功能也比较强大。它可以对负载中的线程组进行复杂的管理。通过在线程计划中具有无限数量的行来完成此操作,这可以为线程组的不同部分启用不同的配置。该插件跟Stepping Thread Group线程组有些类似,不过这个是多个线程组设置的结合。执行的时候,每个线程组是同时按照自己的规则开始执行的,每一时刻,得到的结果都是两个线程组的叠加。
形象比喻:
并发的用户就像浪花一波一波的不断涌入系统,拍打服务器,考验我们的系统能否顶住压力并平稳运行
我们的网站正在平稳运行的时候,突然有一波1000用户同时访问,我们称之为第一浪潮。访问了30s之后,第一浪潮在15s内逐渐退出系统。
在第一浪潮退出系统的同时,第二波2000用户在极短时间内又突然涌入网站,我们称之为第二浪潮。在访问30s之后,第二浪潮在15s内也逐渐退出了系统。
在第二浪潮退出系统的同时,第三波3000用户又突然涌入网站,我们称之为第三浪潮。在访问30s之后,第三浪潮在15s内也逐渐退出了系统。
在第三浪潮退出系统的同时,第四波1000用户又突然涌入网站,我们称之为第四浪潮。在访问30s之后,第四浪潮在15s内也逐渐退出了系统。
添加单个线程组Row 和 添加多个线程组Row:
图中本次测试一共启动100个线 编辑程(用户/并发)。
· Initial Delay, sec:最开始延迟时间,单位秒。设置为0,就是点击了立即执行。
· Startup Time, sec:启动设置的100个线程并发一共需要的时间,单位秒。图中设置10秒(线程组的加速期)
· Hold Load For, sec:保持加压时间,单位秒。图中10秒。
· Shutdown Time:多久时间内全部释放关闭,单位秒。图中10秒。
【实例】
1、需求:要求此接口用户的访问量“分波式”访问,每个时期、每波都有不同用户量访问,每波的用户访问量呈现出递增然后逐次递减的状态,单波用户量最大并发不可超过70。
2、分析:根据需求实现具体场景,可得出普通线程组并不能实现,普通线程组一般实现为“直线式”的需求场景(配合其他元件实现略不同),那么此时Ultimate Thread Group线程组便可为之实现:
3、步骤:
第一步:根据需求场景“每个时期、每波都有不同用户量访问”现设置添加多Row,每Row的Start Threads Count(开始线程计数),初始用户的数量为:10、30、50、70、50、30、10,此时每波用户访问量递增→递减和单波用户不可超过70的需求配合关闭时间已经满足。
第二步:每Row的Initial Delay,sec(延迟启动时间,单位秒)设置每时间间隔5s:0s、5s、10s、15s、20s、25s、30s,这样是为了满足不同组的启动延迟时间,若每个线程组不同的用户都在同一时间节点启动那不是递增式并发,那是同步式并发。
第三步:每Row的Startup Time,sec(启动时间),意指每个线程组的线程在多少s内全部启动,目前设置为1s,即是每组线程组的线程数从启动开始到启动结束话费时长为1秒。
第四步:每Row的Hold Load For,sec(持续运行),意指每个线程组的线程在启动达到设置的线程数后持续运行多长时间,单位秒。此时需求每组线程运行后达到顶峰后呈现出“递减”状态,所以持续运行时间应该也是设置为递减:30、25、20、15、10、5、0(单位s)。
第五步:Shutwn Time(关闭时间),这个可配合上面四个可设置:0、5、10、15、10、5、0。这样是为了满足“每波用户访问量递增→递减”的需求
好啦主功能配置已经完成,看下具体线程组效果图:
此时,运行后为了确保线程组的变化运行轨迹,添加一个Active Threads Over Time用来查看随时间变化的活动线程:(添加路径:线程组→添加→监听器→jp@gc - Active Threads Over Time)
最后,即可添加察看结果树、聚合报告、响应时间图等分析此接口的接口各个返回指标等:
Ultimate Thread Group(最终线程组)实现原理:TA跟Stepping Thread Group线程组有些类似,不过这个是多个线程组设置的结合。执行的时候,每个线程组是同时按照自己的规则开始执行的,每一时刻,得到的结果都是两个线程组的叠加。
二、HTTP请求默认值
1、添加HTTP请求默认值
作用:可以填写请求协议、服务器地址等,放在线程组下面整个线程组的http请求会自动调用这些内容。
线程组右键--添加--配置原件--HTTP请求默认值
分别填写上协议、服务器地址、编码、端口号,后续的请求就不用填写这三项了。而且,如果想从测试环境切换到正式环境,直接再http请求默认值里面更换服务器地址就可以了。
三、HTTP请求
客户端发送的HTTP请求到Web服务器时,请求消息主要包含:
请求行
请求头
请求体(请求报文/请求参数)
1.1 请求行
请求行用于说明请求类型,以及要访问的资源和使用的HTTP版本。
请求行包含以下内容:
请求方法: HEAD、GET、POST、PUT、OPTIONS、DELETE、PATCH
HTTP定义了很多于服务器交互的方法:
GET 请求指定的页面信息,并返回实体主体
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
PUT 向Web服务器发送数据,并存储在Web服务器内部
HEAD 检查一个对象是否存在
DELETE 从Web服务器上删除一个文件
CONNECT 对通道提供支持
TRACE 跟踪到服务器的路径
OPTIONS 查询Web服务器的性能
请求地址
HTTP协议/版本
1.2 请求头 headers
请求头headers用于指定服务器要使用的附加信息
Accept:指定客户端能够接收的内容类型,如:Accept: text/plain, text/html
类型中的先后次序表示客户端接收的先后顺序
Accept-Charset:浏览器可以接受的字符编码集。
Accept-Encoding:指定浏览器可以支持的web服务器返回内容压缩编码类型。
;Accept-Encoding允许Web服务器将输出内容发回客户端之前进行压缩,以节约带宽。这里设置的就是客户端浏览器所能够支持的压缩格式。
简单来说,就是Web服务器在给客户端返回页面数据之前,将数据以gzip格式进行压缩,也节省带宽,加快传输。
说明:
gzip 是GNU zip的缩写,是GNU自由软件的文件压缩程序,也用来表示gzip文件格式。
deflate 使用LZ77算法于哈夫曼编码(Huffman Coding)的一种无损压缩算法
Accept-Language:浏览器可接受的语言
说明:
zh-cn表示简体中文
zh 表示中文
q 表示权重系数,范围0~1,q值越大请求越倾向于获取;之前的类型所表示的内容,若没有指定q值则默认为1。若q值为0则用于提醒服务器哪些是浏览器不接受的内容类型。
Accept-Ranges:可以请求网页实体的一个或者多个子范围字段
Authorization:HTTP授权的授权证书
Cache-Control:指定请求和响应遵循的缓存机制
Connection:表示是否需要持久连接。如果Web服务器接收到Connection的属性值为Keep-Alive,或者请求所使用的协议版本是HTTP 1.1(默认持久连接),此时就会采用持久连接。
用法:
Connection: keep-alive
当一个Web页面打开时,客户端和Web服务器之间用于传输HTTP数据库的TCP连接不会关闭,如果客户端再次访问Web服务器上的网页,会继续使用这条已经建立的连接。
Connection: close
close表示一个Requset请求完成后,客户端和Web服务器之间用于传输HTTP数据的TCP连接会关闭,当客户端再次发送Request请求时,需要重新建立TCP连接。
Cookie:HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。
Content-Length:请求的内容长度,单位字节(byte),并不包含请求行和请求头的数据长度。
Content-Type:请求的与实体对应的MIME信息,只有在POST方法提交时才需要设置此属性。
当使用POST方式提交数据时,Content-Type属性值支持两种编码类型:
1. application/x-www-form-urlencode
默认缺省的编码类型,表单向Web服务器提交数据时所采用的编码类型。
当向Web服务器发送大量文本、包含非ASCII字符的文本、二进制数据时采用这种编码方式效率很低。
2. multipart/form-data
文件上传时所使用的编码类型,它既可以发送文本数据,也支持二进制数据上传。
在Content-Type属性中还可以指定提交内容的Charset字符编码
Date:请求发送的日期和时间
Expect:请求的特定的服务器行为
Host:指定请求的服务器的域名和端口号
Pragma:用来包含实现特定的指令
Proxy-Authorization:连接到代理的授权证书
Range:只请求实体的一部分,指定范围
Referer:先前网页的地址,当前请求网页紧随其后,即来路
User-Agent:User-Agent的内容包含发出请求的用户信息
2.HTTP response详解
一个http response(http响应)指的是从服务端到客户端的响应消息,它包括了以下信息:
响应行
响应头
响应体(响应报文)
2.1 响应行
报文协议及版本
如:HTTP/1.1 200 OK
状态码及状态描述
1xx: 信息,服务器收到请求,需要请求者继续执行操作
2xx: 成功,操作被成功接收并处理
200 OK:请求成功。 服务器已成功处理了请求。一般用于GET与POST请求
204 No Content:无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档。一般用在只是客户端向服务器发送信息,而服务器不用向客户端返回什么信息的情况。不会刷新页面。
206 Partial Content:部分内容。服务器成功处理了部分GET请求。响应报文中包含Content-Range指定范围的实体内容
3xx: 重定向,需要进一步的操作以完成请求
301 Moved Permanently:永久移动。资源(网页等)被永久转移到其它URL。服务器返回此响应(对GET或HEAD请求的响应)时,会自动将请求者转到新位置。
302 Found:临时移动。 资源只是临时被移动,请求者应继续使用原有位置来进行以后的请求。
303 See Other:临时重定向,应使用GET定向获取请求资源。303功能与302一样,区别只是303明确客户端应该使用GET访问。
304 Not Modified:未修改。 所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源。
305 Use Proxy:使用代理。所请求的资源必须通过代理访问
307 Temporary Redirect:临时重定向。服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
4xx: 客户端错误,请求包含语法错误或无法完成请求
400 Bad Request: 客户端请求的语法错误,服务器无法理解
401 Unauthorized: 请求要求用户的身份认证,这个状态代码必须和WWW-Authenticate报头域一起使用。
403 Forbidden: 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found: 服务器无法根据客户端的请求找到资源(网页)
415 Unsupported media type:服务器无法处理请求附带的媒体格式
5xx: 服务器错误,服务器在处理请求的过程中发生了错误
500 Internal Server Error: 服务器内部错误,无法完成请求
502 Bad Gateway: 网关错误。充当网关或代理的服务器,从远端服务器接收到了一个无效的请求
503 Server Unavailable:由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
505 HTTP Version not supported: 服务器不支持请求的HTTP协议的版本,无法完成处理
HTTP状态码大全
2.2 响应头
Accept-Ranges:表明服务器是否支持指定范围请求及哪种类型的分段请求
Age:从原始服务器到代理缓存形成的估算时间(以秒计,非负)
Allow:对某网络资源的有效的请求行为,不允许则返回405
Cache-Control:告诉所有的缓存机制是否可以缓存及哪种类型,常见的取值有常见的取值有private、public、no-cache、max-age,no-store,默认为private。
Content-Encoding:web服务器支持的返回内容压缩编码类型
Content-Language:响应体的语言
Content-Length:响应体的长度
Content-Location:请求资源可替代的备用的另一地址
Content-Range:在整个返回体中本部分的字节位置
Content-Type:返回内容的MIME类型
Date:原始服务器消息发出的时间
Expires:响应过期的日期和时间
Location:用来重定向接收方到非请求URL的位置来完成请求或标识新的资源,需要与状态码302配合使用,完成跳转。
Pragma:包括实现特定的指令,它可应用到响应链上的任何接收方
Proxy-Authenticate:它指出认证方案和可应用到代理的该URL上的参数
Server:web服务器软件名称
Set-Cookie:设置Http Cookie
Transfer-Encoding:文件传输编码
Vary:告诉下游代理是使用缓存响应还是从原始服务器请求
Via:告知代理客户端响应是通过哪里发送的
WWW-Authenticate:表明客户端请求实体应该使用的授权方案
2.3 响应体
响应体是服务器回写给客户端的页面正文,浏览器将正文加载到内存,然后解析渲染 显示页面内容
四、HTTP信息头管理器
信息头,也就是请求头,它会随着我们的HTTP请求一起发送到服务器,比如需要传输User-Agent 、cookie、token或其他某些信息,或是需要伪造请求头的时候。
在http请求之前添加一个HTTP信息头管理器,将所需的头信息以键值对的方式添加进去,能使你能够更真实的模拟该接口的访问,在后边的HTTP请求发送时则将使用该管理器中的header信息。
右键> 添加 - 配置元件 - HTTP信息头管理器
PS: 头部管理器也可以添加管理cookie, 与cookie管理器相比, 这里并不需要添加服务器域名
头部信息合并&覆盖
JMeter是支持多个头部管理器的,允许添加多个HTTP请求头, 多个请求头或合并或覆盖;
若存在多个头部管理器, 头部信息会合并;
如果要合并的头部信息与现有的头部名称匹配, 它将替换先前的头部信息;
头部的信息值为空不会删除现有的头部信息, 而只是替换其为空值;
同一作用域下,不论添加多少个头部管理器, 只会取第一个管理器的值, 不合并;
逻辑控制器下的头部管理器C会与线程组和测试测试计划下的头部管理器B与A合并,若头部名称相同则C会替换B和A的值,作用域:仅一次控制器下的HTTP取样器
线程组下的头部管理器B会与测试测试计划下的头部管理器A合并, 若头部名称相同则B会替换A的值,作用域:该线程组下的HTTP取样器
测试计划下的头部管理器A, 作用域:测试计划下的所以线程组的HTTP取样器
同一线程组下作用域完全重叠的管理器B和D, 在该线程组下的HTTP请求头部只会取管理器B的头部信息, 不取管理器D的头部信息
五、查看结果树
1、添加查看结果树
2、查看结果树的位置
查看结果树如果放在线程组下,运行之后就显示整个线程组的所有接口的运行结果,如下
查看结果树放在单接口下,运行后只显示该接口的运行结果,如下
六、断言
作用:判断接口返回的结果是正确的
1、添加断言
选择接口右键--添加--断言--响应断言
2、断言填写
七:运行
八、清除
想清除之前的运行记录,可以点击顶部的扫把
九、jmeter的参数化
在接口测试的时候,有些接口会用到大量的数据,比如注册的时候需要100个账号,这个时候就要用到参数化,参数化有两种方法。
方法1、通过csv做参数化
第一步:在桌面新建一个表格,表格内容填写如下
第二步:在jmeter中添加CSV配置元件
优点:可以测试接口的异常情况,比如注册接口再做参数化的时候可以把账号、密码分别设置为空,账号设置为30位数等等。
线程组右键--添加--配置元件--CSV Data Set Config
设置CSV配置元件
在http请求中引用,引用方法${变量名称}
因为CSV文件中写了10条数据,所以在线程组这里把线程数设置为10,再点击运行。
方法2、通过计数器做参数化
1、添加计数器
线程组右键--配置元件--计数器