ps: 要先配置好java环境,这里我之前就已经配置好了,不用再重新配置
把安装包复制到某个目录下,这里我选择放在/usr/local/jmeter
目录(先在/usr/local
通过 sudo mkdir jmeter
命令新建jmeter目录
解压
tar -xzvf apache-jmeter-5.4.3.tgz
vim
编辑/etc.profile
文件:
vim /etc/profile
在最底部新增以下配置:
export JMETER_HOME=/usr/local/jmeter/apache-jmeter-5.4.3
export PATH=$PATH:${JMETER_HOME}/bin
source /etc/profile
jmeter --version
或jmeter -v
检查环境是否配置好/usr/local/jmeter/apache-jmeter-5.4.3/bin
目录,使用./jmeter.sh
启动jmeter U
i:Apach Jmeter是Apach组织开发的基于java的一款性能测试工具
取样器:进行脚本逻辑控制
线程组:场景设置
监视器:监视脚本运行,取得性能指标
Jmeter使用单个线程模拟一个用户,线程组(Thread Group)就是指一组用户,作为模拟访问被测系统的虚拟用户组
线程数(Number of Threads)
线程属性中的线程数可以用来配置虚拟用户组的并发用户数,数值越高,并发量越大。增加一个线程就是多一个模拟用户,
Ramp-Up Period(in seconds)
可以翻译为”建立时间“,确保在这个时间内,所有线程都要被全部建立起来
例如: 线程数设置为5,Rame-Up Period设置为5,那相当于在5秒内,这5个线程都要被建立起来,每个线程建立的时间间隔为5/5=1s
循环次数Loop Count
表示每个线程会循环发起多少次请求
比如当线程数设置为1,Rame-Up 时间设置为1,循环次数设置为5,那么这个线程会每隔1s发送一个请求,直至发送完5个请求
如果线程数设置为5,Rame-Up时间设置为5,循环次数为2。那么代表将在5秒内启动5个线程,同时每个线程内重复2次请求
线程数为1时,Rame-Up时间将不起作用。例如线程数为1,Rame-Up为5,Loop Count为60,那么每个重复的请求将于上一次请求结束后发起,如果每次响应时间是500ms,那么上面60次Loop将于30s结束
结论:
Jmeter将在Rame-Up 时间内,启动Number of Threads个线程。并且利用每个线程重复发出Loop Count 次请求。
线程收到响应后,即发出Loop内的下一个请求
线程的请求Loop次数达到之后,线程就会被销毁
在jmeter的bin目录下执行以下命令,会在相应目录下生成结果文件jtl
jmeter -n -t /usr/local/jmeter/jmeter_srcipts/first_test01.jmx -l /usr/local/jmeter/jtls/first_test01.jtl
-n
表示非GUI模式下执行Jmeter
-t
表示执行测试文件所在的位置以及文件名
-r
表示远程将所有agent启动用在分布式测试场景下,不是分布式测试只是单点就不需要-r参数
-l
表示指定生成测试结果的保存文件,jtl格式
ps:-l
指定的生成的测试结果的文件夹或目录,必须是空的,否则会报错
jmeter -n -t /usr/local/jmeter/jmeter_srcipts/first_test01.jmx -l /usr/local/jmeter/jtls/first_test01.jtl -e -o /usr/local/jmeter/resultReport
-e
表示测试结束后,生成测试报告
-o
表示指定测试报告的存放位置
然后到生成测试报告的resultReport目录下,可以看到已经生成了测试报告,可以用浏览器打开html文件查看测试报告
还可以用已存在的结果文件jtl去生成测试报告,命令为:
jmeter -g /usr/local/jmeter/jtls/first_test01.jtl -e -o /usr/local/jmeter/resultReport
-g
表示指定已存在的测试结果的文件以及位置
ps:-o
指定的文件或文件夹,必须里面是空的,否则会执行失败
可以使用badboy(不支持linux)录制脚本导出脚本jmx文件到jmeter去导入使用
导入录制好的脚本导入到jmeter中
在线程组上添加监听器-察看结果树
HTTP请求默认值
Jmeter测试计划添加HTTP代理服务器
浏览器设置代理服务器
设置完以上之后,在浏览器进行操作,就会在Jmeter中形成脚本
在HTTP请求右键点击添加'配置元件',选择'用户定义的变量'
例如定义了一个host
变量,那在请求中可以使用${host}
进行调用
可以通过函数助手-CSVReader,也可以通过配置元件-CSV数据文件设置进行配置
通过菜单栏-工具-函数助手对话框进行添加
路径:通过菜单栏-工具-函数助手对话框进行添加
例如,csv文件中的内容如下:
xiaoming,13
xiaohong,12
xiaolan,14
xiaomei,13
填写完之后,点击生成就会生成供请求调用的函数字符串
在请求中这样调用:
路径:HTTP请求-添加配置元件-CSV数据文件设置
ps:这个与postman很像
配置好csv数据文件之后,在请求中使用${}
进行调用:
关联是指上一个接口的返回数据需要被下一个接口的请求用到,则需要对上一个接口请求的响应报文使用后置处理器,最常使用的是正则表达式提取器,json提取器
LoadRunner与Jmeter关联的不同之处:
LoadRunner中的关联函数是写在要获取变量值的页面的前面;在Jmeter中关联函数是要写在要获取变量值的页面的后面
在LoadRunner中关联函数是注册函数,在Jmeter中使用正则表达式等提取器进行关联
HTTP请求-后置处理器
允许用户从作用域内的取样器(sampler)请求的服务器响应结果中通过正则表达式提取所需值,生成模板字符串,并将结果存储到设置的变量中
Main sample and sub-samples:作用于主节点的取样器及对应子节点的取样器
Main sample only:仅作用于主节点的取样器
Sub-samples only:仅作用于子节点的取样器
JMeter Variable:作用于jmeter变量(输入框内可输入jmeter的变量名称),从指定变量值中提取需要的值。
主体:响应报文的主体,最常用
Body(unescaped):主体,是替换了所有的html转义符的响应主体内容,注意html转义符处理时不考虑上下文,因此可能有不正确的转换,不太建议使用
Body as a Document:从不同类型的文件中提取文本,注意这个选项比较影响性能
Response Headers:响应信息头
Request Headers:请求信息头
URL:请求url
Response Code:响应状态码,比如200、404等
Response Message:响应信息
引用名称
指的是提取出来之后要赋值的变量名,用来存储提取的结果
要提取到多个值的时候用;隔开
在HTTP请求中通过${设置的引用名称}
调用提取出来的值
正则表达式
使用正则表达式解析响应的结果
匹配的两种模式,比如有以下响应数据:
"code":"0","msg":"请求成功","bizSeqNo":"1804242UD01154300109392900987311" ,"result":{"bizSeqNo":"1804242UD01154300109423800987316","transactionTime":"20180424094239"
提取bizSeqNo的值:
贪婪模式:"bizSeqNo":"(.*)":贪婪模式,提取结果是:1804242UD01154300109392900987311" ,"result":{"bizSeqNo":"1804242UD01154300109423800987316","transactionTime":"20180424094239
非贪婪模式"bizSeqNo":"(.*?)":非贪婪模式,提取结果是:1804242UD01154300109392900987311:
模板
正则表达式的提取模式。
如果提取结果有多个,则结果为数组形式,模板$1$,$2$等等,表示把解析到的第几个值赋值给变量,从1开始匹配
匹配数字
正则表达式匹配数据的结果可以看作是一个数组,表示如何取值:0表示随机取值,1表示取第一个值,负数则代表提取所有符合条件的值
缺省值
匹配失败的时候的默认值,通常用于后续的逻辑判断,一般通常定义为特定含义的大写英文字母组合,如ERROR
通过元素属性编写表达式://标签[@属性=‘属性值’],示例://input[@name='username'] 同时使用两个属性定位://input[@name='username'and @class='input'] 同名元素拥有某个属性而没有另一个属性://input[@name='username'and not(@class)]
通过索引编写表达式:通过元素层级定位,示例://header/div/nav/ui/li[3] (注意:xpath中序号从1开始)
通过text编写表达式:text为完全匹配,需要输入全部文字;示例://a[text()='登录']
通过contains编写表达式:contains为部分匹配,只需输入部分文字;示例://a[contains(text(),'登录')]或//a[contains(text(),'登')]
通过string编写表达式:元素内容被子元素截断时,通过text无法定位,可以使用string;示例://a[string()='登录']
举例:
//*[@class,'A ']/@href 从根目录下定位所有class=A的href
//*[@class,'A '] 从根目录下定位所有class=A标签内的文本
//*[contains(@class,'A ')] 从根目录下@class值中包含A的节点
substring-before(.//*[@class='A']/text(),'0') 返回根目录下[@class='A']/text()中第一个'0'前面的部分,如果不存在'0',则返回空值
substring-after(.//*[@class='A']/text(),'0') 返回根目录下[@class='A']/text()中第一个'0'后面的部分,如果不存在'0',则返回空值
专门用来对返回结果是application/json格式的报文进行提取
可以在察看结果树中左侧设置JSON Path Tester
,然后在JSON Path Experssion
中进行编写Json Path表达式并且进行Test
,可以验证取出来的数是不是预期想要的,一步步进行调试
也可以在json解析网站查看对应返回json数据的结构
是一个轻量级的面向java的脚本语言,使用了Jmeter对于BeanShell支持的特性,允许使用标准的java语法来处理json数据
需要下载第三方json解析的jar包(fastjson),把jar包放在jmeter的lib目录下
在测试计划中把jar包加载进来
在需要获取接口返回值的接口处添加BeanShell后置处理程序
在script中编写java代码,获取接口响应数据并解析,取得想要提取出来的变量值并赋值给一个变量
可以使用XXX.put("变量名","取出来的值")进行存储
在需要这个变量的请求中使用${变量名}
进行调用
utf-8
如果还不行的话,到2
打开jmeter的bin
目录下的jmeter.properties
进行编辑
先通过sampleresult.default.encoding
搜索到该内容
把编码改成UTF-8:
最后关闭jmeter重新打开即可
添加BeanShell后置处理程序,在script中写prev.setDataEncoding("utf-8")
样本数
等于用户数x循环次数
例如设置了线程数为5,循环次数为10,那样本数为50
平均值(Average)
单个请求的平均响应时间,单位是ms
中位数(Median)
50%用户的请求时间,单位为ms
90%百分位(90% Line)
90%用户的请求时间,单位为ms
ps:95%百分位,99%百分位以此类推
最小值(Min)
单个请求最小的响应时间,单位为ms
最大值(Max)
单个请求最大的响应时间,单位为ms
异常%(Error %)
有问题的请求数/样本
吞吐量(Throughput,即TPS)
单位不定,慢的时候是请求数/小时,即单位小时内能处理的请求数;快的时候是请求数/秒,即每秒能处理的请求数
接收kb/sec
每秒从服务器接收返回数据所占带宽。越小约好,代表占用的带宽越小
发送kb/sec
每秒从服务器发送的数据量
在响应时间中,在实际工作中比较关心90%百分位这个值
需要模拟用户高并发场景时,可以使用jmeter的集合点模拟测试
解决“无法控制瞬间并发量”的问题
使用集合点,阻塞线程,等达到一定数量线程之后,再一起释放,可以瞬间产生很大压力
集合点(Synchronizing Timer)是在每个取样器之前执行的
当执行一个取样器时,和取样器处于相同作用域的定时器都会被执行
如果希望定时器仅应用于其中一个取样器,则把该定时器作为子节点加入
添加集合点(synchronized timer)
设置Number of Simulated Users to Group by
即每集合等多少个线程到达后发送一次测试请求
例如:“Number of Simulated Users to Group by: 5”表示并发量是5。也就是说,Jmeter会等到5个线程都运行到此处时,这五个线程才开始执行后面的操作,先到达的线程将会在此等候。
设置Timeout in milliseconds
即超时时间,多少毫秒后同时释放已经集结的线程,发送测试请求
如果设置为0,Timer将等待线程数达到了"Number of Simultaneous Users to Group"中设置的值才释放。如果大于0,那么如果超过Timeout in milliseconds中设置的最大等待时间(毫秒为单位)后还没达到"Number of Simultaneous Users to Group"中设置的值,Timer将不再等待,释放已到达的线程。
设置线程组属性
线程组属性的Rame-UP时间可以设置较长时间,这样测试机器的压力会小一点