jmeter元件的执行顺序
1、配置元件(Config Elements)
2、前置处理器(Pro-processors)
3、定时器(Timers)
4、取样器(Sampler)
5、后置处理器(Post-processors)
6、断言(Assertions)
7、监听器(Listeners)
注:1,前置处理器、后置处理器和断言等元件功能对取样器作用。因此,如果在它们的作用域内没有任何取样器,则不会被执行;
2,如果在同一作用域范围内有多个同一类型的元件,则这些元件按照它们在测试计划中的上下顺序依次执行
jmeter目录结构
Jmeter断言
响应的json数据
响应断言(判断是否包含内容)
断言失败的话显示
大小断言(判断字节数)
Json断言
Xpath断言(后面会写xpath的简单用法)
断言持续时间(判断响应的时间)
Xpath基本语法
符号 | 描述 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑他们的位置 |
. | 选取当前节点 |
* | 匹配任何元素节点 |
@* | 匹配任何属性节点 |
node() | 匹配任何类型节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |
/div[1] | 选取div元素的第一个 |
/div[last()] | 选取div元素的最后一个 |
/div[position()<3] | 选取div元素的前俩个当然也有=,!=,<,> |
//input[@length>256] | 选取input的lenght元素大于256的 |
//div[@class="wd"] | 选取div元素的class属性等于wd的 |
//div[@name='rn'] | //div[@name='oq'] | 选取div元素的name属性等于rn和oq的 |
//p[@id="cp"]/text() | 选取元素下所有的文本当然不包括标签内部的文本 |
XPath轴(XPath Axes)可定义某个相对于当前节点的节点集:
1、child 选取当前节点的所有子元素
2、parent 选取当前节点的父节点
3、descendant 选取当前节点的所有后代元素(子、孙等)
4、ancestor 选取当前节点的所有先辈(父、祖父等)
5、descendant-or-self 选取当前节点的所有后代元素(子、孙等)以及当前节点本身
6、ancestor-or-self 选取当前节点的所有先辈(父、祖父等)以及当前节点本身
7、preceding-sibling 选取当前节点之前的所有同级节点
8、following-sibling 选取当前节点之后的所有同级节点
9、preceding 选取文档中当前节点的开始标签之前的所有节点
10、following 选取文档中当前节点的结束标签之后的所有节点
11、self 选取当前节点
12、attribute 选取当前节点的所有属性
13、namespace 选取当前节点的所有命名空间节点
实例::要定位当前td同级后的一个td
//td[@id='dw']/following-sibling::td
Jmeter参数化的常用方式
jmeter参数化__函数助手_csvRead
1,点击1位置弹出函数助手的弹窗
2,点击2位置选择功能函数
3,点击3位置输入csv文件的路径如:C:\Users\Administrator.USER-20181127ZE\Desktop\1.csv
4,点击4位置输入0的话表示从第一列开始
5,点击5位置自动生成引用名
6,引用方法如图
jmeter参数化__用户参数
1,前置管理器——用户参数
2,如图设置参数
3,直接引用就可以了 用户1的下面的俩个参数都是对应的
jmeter参数化__csv数据文件设置
(所有参数化涉及到的csv文件的文本都是这样的)
1,配置元件——csv数据文件设置
2,文件名选择文件
3,文件编码一般都是utf-8
4,自定义引用名 一行有俩列话就俩个引用名以,(英文的)分割
由于我没有的表格没有设置首行为表头所以不用忽略首行
5,csv文件的默认分隔符就是,
6,带引号根据自己的情选择 剩下的都写的很明白不用细说
7,引用方法和上边的一样
jmeter参数化__函数助手__random string(随机函数)
1,如图第一个输入框填写选取的个数
2,第二个输入框输入待选择的文本
3,第三个输入框输入引用名
4,点击生成 其实就是生成了一个函数表达式(你可以不用这么麻烦的设置函数助手什么的可以直接在引用名上如数该函数)
Jmeter参数化__JDBC
1,前提是安装mysql数据库后查看版本下载对应的数据库驱动
2,点击TestPlan在图中位置导入数据库驱动
3,添加-配置元件-JDBC Connection Configuration
Variable Name: 变量名称
Max Number of Connection: 数据库最大链接数
PoolTimeout: 数据库链接超时,单位ms
Idle Cleanup Interval (ms): 数据库空闲清理的间隔时间,单位ms
Auto Commit:自动提交。有三个选项,true、false、编辑(自己通过jmeter提供的函数设置)
Transaction Isolation:
事务间隔级别设置,主要有如下几个选项:
【TRANSACTION_NODE 事务节点 、
TRANSACTION_READ_UNCOMMITTED 事务未提交读、
TRANSACTION_READ_COMMITTED 事务已提交读 、
TRANSACTION_SERIALIZABLE 事务序列化 、
DEFAULT 默认、
TRANSACTION_REPEATABLE_READ 事务重复读、
编辑】
Database URL:如jdbc:mysql://localhost:3306/test 表示本地数据库,3306端口,数据库名称为test后面还有参数稍后补充
?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=UTC
JDBCDriver Class: JDBC的类,如org.gjt.mm.mysql.Driver
4,添加取样器-JDBC Request
第一个空和前面的对应
Varivble names:对应的应用名 多个以逗号分隔
Result Varivble name:对应的查询全部集合的引用名
5,正常引用变量就可以了
向数据库中插入数据
jmeter定时器
固定定时器
1,定时器——固定定时器
2,设置线程延迟时间
3,即表示在执行改该请求的时候每个请求之间的间隔是10000毫秒(第一个请求也是10000毫秒之后执行的)
同步定时器
1,定时器--同步定时器
2,当线程数设置为100的时候
3,等到50个,未超时,继续等待,等到时间到了 一起并发(此时的线程数可能大于50)
4,未等到50个线程。时间到了 此时等待到多少个线程并发多少个线程
1,设置线程数为100
2,等带到60个的时候并发一次,继续等待等待到40达不到60所以一直等待不运行(只会运行一次等待到60的时候)
高斯随机定时器
如需要每个线程在请求前按随机时间停顿选取高斯随机定时器
统一随机定时器
和高斯随机定时器的作用差异不大,区别在于延时时间在指定范围内且每个时间的取值概率相同,每个时间间隔都有相同的概率发生,总的延迟时间就是随机值和偏移值之和。
泊松随机定时器
这个定时器在每个线程请求之前按随机的时间停顿,大部分的时间间隔出现在一个特定的值,总的延迟就是泊松分布值和偏移值之和
常数吞吐量定时器
精准吞吐量定时器
jmeter逻辑控制器
一、简单控制器(Simple Controller)
作用:这是Jmeter里最简单的一个控制器,它可以让我们组织我们的采样器和其它的逻辑控制器(分组功能),提供一个块的结构和控制,并不具有任何的逻辑控制或运行时的功能。
二、循环控制器(Loop Controller):
作用:指定其子节点运行的次数,可以使用具体的数值(如下图,设置为5次),也可以使用变量
1、Forever选项:勾选上这一项表示一直循环下去
2、如果同时设置了线程组的循环次数和循环控制器的循环次数,那循环控制器的子节点运行的次数只根据循环控制器的次数进行,不和线程组的循环次数有关系,这点要记住。(注:这个本人实测结果相反)
注意:要用循环控制器,那么需要控制器下面有请求才能使用
三、仅一次控制器(Once Only Controller):
如图设置一个循环控制器 在循环控制器中创建一个仅一次控制器,无论循环控制器执行多少次,仅一次控制器就执行一次
作用:在测试计划执行期间,该控制器下的子结点对每个线程只执行一次,登录场景经常会使用到这个控制器。
注意:将Once Only Controller作为Loop Controller的子节点,Once Only Controller在每次循环的第一次迭代时均会被执行。
四、ForEach控制器(ForEach Controller):
作用:ForEach控制器一般和用户自定义变量一起使用,其在用户自定义变量中读取一系列相关的变量。该控制器下的采样器或控制器都会被执行一次或多次,每次读取不同的变量值。如下图:
参数:
Input Variable Prefix:输入变量前缀
Output variable name:输出变量名称
Start index for loop(exclusive):循环开始的索引(这里如果不填写,默认从1开始,如果没有1开始的变量,执行时会报错)
End index for loop(inclusive):循环结束的索引
Add”_”before number:输入变量名称中是否使用“_”进行间隔。
用户自定义变量:
变量名前缀为ForEach Controller中Input variable prefix定义的name + 下划线(上图中我们勾选了下划线)+数字编号
执行结果:
总共执行了3次,每次执行时会把获取到的变量值赋值给输出变量outNmae,其它地方可以通过${outNmae}进行调用。
五、事务控制器(Transaction Controller):
这个多应用在性能测试中,当多个api进行性能测试的时候,我们在使用聚合报告查看的时候数据比较杂乱,这个时候我们就可以把这些api看做一个事物,进行聚合报告查看
作用: 事务控制器会生产一个额外的采样器,用来统计该控制器子结点的所有时间。
参数:
Generate parent sample:(选中这个参数结果展示如下图红框,否则显示为下图蓝框)
Include duration of timer and pre-post processors in generated sample:选中这一项会统计定时器(timer)的时间,否则只统计采样器(sample)的时间
六、If 控制器(If Controller):
作用:根据给定表达式的值决定是否执行该节点下的子节点,默认使用javascript的语法进行判断(如下图红框内的文字)。
参数:
Interpret Condition as Variable Expression?:选中这一项时表示:判断变量值是否等于字符串true(不区分大小写)
Evaluate for all children:如果选中这一项,在每个子结点执行前都会计算表达式
示例一:使用变量的方式进行判断:
说明:${test}获取的值判断是否等于tom,如果等于即执行if控制器,不等于则跳过if控制器
注意:条件需要增加“”
示例二:选中Interpret Condition as Variable Expression?
七、Switch控制器(Switch Controller):
作用:Switch控制器通过给该控制器中的Value赋值,来指定运行哪个采样器。有两种赋值方式:
第一种是数值,Switch控制器下的子节点从0开始计数,通过指定子节点所在的数值来确定执行哪个元素。
第二种是直接指定子元素的名称,比如采样器的Name来进行匹配。当指定的名称不存在时,不执行任何元素。
当Value为空时,默认执行第1个子节点元素。
八、吞吐量控制器(Throughput Controller):
作用:控制其下的子节点的执行次数与负载比例分配,也有两种方式:
Total Executions:设置运行次数
Percent Executions:设置运行比例(1~100之间)
示例:
1、设置线程组循环5次:
2、Throughput Controller1的子结点执行3次:
3、Throughput Controller2的子结点执行(40% * 线程组循环次数5)= 2次:
执行结果:
九、随机控制器(Random Controller):
作用:随机执行随机控制器下面的某一个请求
十、随机顺序控制器(Random Order Controller):
全部执行随机顺序控制器中的请求,只是顺序是随机的
十一、while控制器
框中的值为true则退出循环,否则值为false则一直循环
十二、临界部分控制器
业务逻辑:
根据锁名来控制并发,同一个锁名之下,在同一时间点只能存在一个运行中,适用于控制并发的场景
锁名类型:
锁名为空,认为每个锁为不同的锁
锁名相同,多个锁认为是同一个锁,同一个时间点只能存在一个运行中
锁名为变量,根据变量值来判断是不是属于同一个锁,变量值为相同时,则认为是同一个锁
十三、include(包含)控制器
引入的必须是测试片段
执行结果入下图
十四、交替控制器
10个线程执行结果如下
十四、交替控制器
十五、录制控制器
咱也不敢说咱也不敢问估计是个没有用的控制器吧
十六、Runtime控制器
表示该控制器下面的请求会执行5秒
jmeter中常用函数
${__TestPanName},返回当前测试计划的名称
${__threadGroupName},返回当前线程组的名称
${__threadNum},返回当前正在执行的线程的编号,而且不依赖于线程组
${__samplerName},返回当前请求的名称
${__machineName},返回本机的主机名
${__random},随机生成数字
${__randomstring},随机生成字符串
${__time},多种格式返回当前时间
${__time()} 返回'1548133155699'
${__time(YMD,)} 返回'20190122'
${__time(dd/MM/yyyy,)} 返回'22/01/2019'
${__time(yyyy-MM-dd HH:mm:ss,)} 返回2020-05-12-20-25-12
${__P(group1.threads)}:返回属性group1.threads的值。
${__P(group,wangruifeng},返回group的值没有的话返回默认值wangruifeng
${__setProperty},用于设置JMeter属性的值。
${__counter(FALSE,num)},计数器从1开始
Jmeter正则表达式提取器的使用
正则语法
符号 | 描述 |
. | 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. |
* | 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \* |
\d | 表示任意一个数字 |
\s | 匹配任意的空白符,包括空格,换行符,制表符(tab) |
\w | 匹配字母,数字,下划线或汉字 |
^ | 匹配字符串的开始 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结尾的位置 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。 |
注意:*、+限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。
Apply to:应用范围
要检查的响应字段:样本数据源。
引用名称:其他地方引用时的变量名称,我这里写的phone,可自定义设置,引用方法:${引用名称}
正则表达式:数据提取器,()括号里为你要获取的的值。"mobilephone":"( 相当于LR左边界, )","leaveamount"相当于LR右边界。而括号里\d+为正则表达式,用来匹配所需要获取的数据,何谓正则表达式文章末尾会附上说明
模板:$$对应正则表达式提取器类型。-1全部,0 随机,1第一个2第二个,以此类推,若只有一个正则一般就填写$1$
匹配数字:正则表达式匹配数据的所有结果可以看做一个数组,匹配数字即可看做是数组的第几个元素。-1表示全部,0随机,1第一个,2第二个,以此类推。若只要获取到匹配的第一个值,则填写1
缺省值:匹配失败时的默认值。可以不写。若需用于后续逻辑判断,可简单写为 ERROR。
实例:
如图一个正则匹配多个值 取值的时候 引用名_(第几个)_g1
g1表示只去匹配到的值 g0表示去值和匹配表达式(一般用(.*?)匹配任意字符)
正则表达式中也可以引用变量用${变量名}格式
jmeter常见乱码问题
1,修改图中文件的sampleresult.default.encoding=UTF-8
jmeter设置全局变量
(例如登录获取cookie后面的操作都语言验证就可以使用全局变量)
1,点击函数助手
2,如图复制函数的表达式 取样器——beanshell取样器 粘贴函数表达式
3,引用的时候 ${__P(name)}
jmeter函数助手中常用的函数
${__jexl3(${name}==1,)} 表示当name=1的时候返回值为true,否则为false(注意常用在if循环中,循环控制器)
$(__groovy(${name}==1,)) 效果和上面的一样
注:==等于 !=不等于 >大于等于 >大于 &&且 ||或
jmeter接口测试之上传文件
1、from-data:就是http请求中得multipart/form-data,它会姜表单得数据处理未一条
消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以是上传文件。当
上传得字段是文件时,会有content-type来表明文件类型;content-disposition,用
来说明字段得一些信息;
由于有boundary隔离,所有multipart/form-data既可以上传文件,也可以上传键值
对,它采用了键值对得方式,所以可以上传多个文件
2、x-www-form-urlencoded:就是application/x-www-from-urlencoded,会姜表单内得数据转换为键值对,比如,name=java&age = 23
3、raw:可以上传任意格式得文件,可以上传text,json,xml,html等
4,binary:详单与content-type:application/octet-stream,从字面意思得知,只可以上传二进制数据,通常用来上传文件。由于没有键值,所以,一次只能上传一个文件
注:multipart/form-data与x-www-form-urlencoded区别
multipart/form-data:既可以上传文件等二进制数据,也可以上传表单键值对,只是最后会转换为一条信息
x-www-form-urlencoded:只能上传键值对,并且键值对都是间隔分开得
jemter执行python脚本(我做加密)
方法1:使用bat文件去执行python脚本
os进程取样器
bat脚本如下图
执行的python文件如下图、
用正则匹配出你加密后的字符
然后正常的变量引用就ok
方法2:导入jython的jmeter插件直接调用脚本
jemter常用方法
log:写入日志文件,调试。日志目前有三个级别分别是,info、warn、error
vars:提供读取(get)和写入数据(put)
jmeter使用总常用的方法的总结
获取当前脚本的绝对路径:${__BeanShell(import org.apache.jmeter.services.FileServer;FileServer.getFileServer().getBaseDir();)}
if逻辑控制器条件不能直接写需要使用:${__jexl3(${random_num} == 1 && ${__time(/1000,)}>${s_time},)}
jemter分布式设置总结
负载机(压力机):负责执行线程
主控机:聚合报告可以在主控机上展示
- 主控机和负载机都要安装一样版本的java和jmeter
- 主控机的配置文件jmeter.properties需要修改
- :添加remote_hosts=10.8.88.119:1099。表示的是要控制的负载机(多个负载机,","分隔)。
- :#server.rmi.ssl.disable=false 修改为:server.rmi.ssl.disable=true并且将前面的#注释去掉。
- :将#mode=Standard前面的#注释去掉。这个操作是为了让主控机在执行后在察看结果树下能看到返回的响应信息(repsonse body)
- 负载机的配置文件jemter.properties需要修改
- :#server.rmi.ssl.disable=false 修改为:server.rmi.ssl.disable=true并且将前面的#注释去掉。
- :查询1099端口是否被占用 (netstat -ano | findstr "1099")
- :双击启动 jemter-server.bat 文件
jmeter分布式的步骤以及原理
- 主控机通过jmeter-server的协议将脚本分发给负载机
- 负载机负责执行脚本,负载机执行脚本后会将测试结果发送给主控机
- 主控机也可以是负载机
处理过程
主控机启动后,会拷贝本地的jmx文件分发到远程的负载机上
负载机拿到脚本以后启动命令行执行模式(无界面)去执行脚本,对于负载机拿到的基本都是一样的
执行时。负载机会把执行获得的数据结果传给主控机,主控机会手机所有的负载机的信息并汇总,这样,主控机上就存在一份所有的负载机的汇总数据的结果
常见报错
- 检查主控机和负载机ip是否可以ping的通,检查负载机防火墙是否关闭
- 检查主控机和负载机上的jmeter版本,保证版本一致
- 负载机(加压机)上的JMeter-server.bat没有启动,如果使用主控机127.0.0.1的话,主控机上也要启动
- CSV参数化文件没有复制到负载机同一位置,并且需要保证相同的文件名