JMeter入门操作简介
1、JMter简介及作用
- JMter是Apache公司用Java开发的一款测试工具
- 接口测试、性能测试、数据库测试、java程序测试。
- 可以对服务器、网络或者对象模拟巨大的负载
- 通过带有断言的脚本来验证程序是否能返回预期的结果
2、安装启动
- Java环境安装(基于java开发,需要jdk):https://www.oracle.com/java/technologies/downloads/
- JMter环境安装(需下载不带src的文件):https://jmeter.apache.org/download_jmeter.cgi 下载后解压即可
- 启动:
windows下启动:安装目录/bin/jmeter.bat
linux下启动:cd/安装目录/bin sh jmeter - 中文乱码:
修改:安装目录/bin/jmeter.properties中讲encoding=改为UTF-8
如果解决不了则可以添加后置处理器→ beanshell后置处理程序: prev.setDataEncoding(“UTF-8”); - 默认英文,修改为中文(修改后下次启动默认还是英文)
【Options】–>【Choose language】→【Chinese(simplified)】
修改配置文件,默认语言为中文
安装目录/bin/jmeter.properties,修改配置文件中的language=zh_CN即可
3、环境变量配置(可有可无)
1. 配置环境变量的作用
每次启动前都需要去找jmeter安装目录,在bin目录下启动文件,比较麻烦。配置环境变量后,打开terminal,输入jmeter即可启动,比较方便、减少操作
2. windows下配置(win10为例)
高级系统设置-->环境变量-->系统变量-->新建变量
JMETER_HOME:【jmeter安装目录】
Path变量中添加:%JMETER_HOME%\bin
3. mac下配置:
vim .bash_profile,编辑模式下添加以下配置
export jmeter_HOME=/安装目录/apache-jmeter-5.4.3
export PATH=$PATH:$jmeter_HOME/bin
执行source ~/.bash_profile命令使配置文件生效
4、目录结构
1. bin:可执行文件(包括不限于:Linux/windows启动文件、日志文件、系统配置文件、Linux/windows分布式测试要用到的服务器配置)
2. extras:扩展插件目录。提供了对Ant的支持,可以使用Ant来实现自动化测试,例如批量脚本执行,产生html格式的报表,测试运行时,可以把测试数据记录下来,jmeter会自动生成一个.jtl文件,将该文件放到extras目录下,运行"ant -Dtest=文件名 report",就可以生成测试统计报表。
3. licenses:jmeter证书目录
4. backups:默认存放jmeter保存生成的jmx文件
5. docs:接口文档
6. lib:JMeter依赖的外部jar包
7. printable_docs:用户手册
5、录制脚本方式
1. 手动编辑脚本
简单的hhtp脚本或者java请求脚本(BeanShell Sampler),都可以进行手动编辑,然后创建保存后,进行修改、调试、参数化等等;
2. 代理录制
首先创建一个线程组,再向工作台中添加一个HTTP代理服务器(选中工作台右键-添加-非测试元件-HTTP代理服务器),需要录制的客户端(手机或者电脑设置网络代理为JMeter )然后请求后进行录制;
3. badboy录制(第三方工具)–最快捷方式
使用badboy进行脚本录制,然后导出.jmx格式;这种录制方式录制脚本数据信息比较全面,导出信息经过简单修改就可以进行调试
6、jmeter组件(元件)
1. 执行顺序:测试计划 > 线程组 > 配置元件 > 前置处理器 > 定时器 > (逻辑控制器)> 取样器 > 后置处理器 > 断言/监听器
2. 作用域:可以作用于它的父级组件,同级组件,同级组件的自组件
3. 测试计划:起点、容器
并发执行:默认并发执行
顺序执行:勾选独立运行每个线程组
4. 线程组:虚拟用户
setUp线程组:一个测试计划中最先执行(无关位置)
tearDown线程组 :一个测试计划中最后执行(无关位置)
线程数:组内线程个数(模拟用户数量)
Ramp-Up时间(秒):准备时长:设置的虚拟用户数需要多长时间全部启动。如果线程数为10,准备时长为2,那么需要2秒钟启动10个线程,也就是每秒钟启动5个线程。
循环次数:每个线程循环执行取样器的次数,勾选永远则死循环
持续时间:取样器持续执行时间(会覆盖结束时间)
启动延迟:延迟x秒开始执行取样器(会覆盖启动时间)
5. 取样器:发送请求的最小单元
a. http请求
1. 一般配合http请求默认值、用户定义的变量使用(重复的信息可以写在http请求默认值中,后续http请求则不用重复填写)
2. 名称:用于标识一个sample。建议使用一个有意义的名称
3. 注释:对于测试没任何影响,仅用来记录用户可读的注释信息
4. 协议:向目标服务器发送http请求时的协议,http/https大小写不敏感,默认http
5. 服务器名称或IP:http请求发送的目标服务器名称或者IP地址
6. 端口号:目标服务器的端口号,默认值为80,可不填
7. 方法:GET、POST、HEAD、PUT、OPTIONS、TRACE、DELETE
8. 内容编码:默认为ISO-8859-1,需配置为utf-8
9. 自动重定向:如果选中该项,发出的http请求得到响应是301/302,jmeter会重定向到新的界面,只会有最终响应结果
10. 跟随重定向:如果发出的http请求得到响应是301/302,jmeter会重定向到新的界面,区别是,记录每个步骤的地址
11. keep Alive:jmeter 和目标服务器之间使用 Keep-Alive方式进行HTTP通信
12. 对post使用multipart / from-data (post):当发送HTTP POST 请求时使用,可以上传文件信息,需要在高级→实现中选择java,才可使用
13. 参数 --> 同请求一起发送参数(get请求)
在请求中发送的URL参数,用户可以将URL中所有参数设置在本表中,表中每行为一个参数(对应URL中的 name=value),注意参数传入中文时需要勾选“编码”
14. 消息体上传(post):当发送HTTP POST 请求时使用,json格式数据
15. 文件上传(post):当发送HTTP POST 请求时使用
16. 文件名称:文件路径
17. 参数名称:请求参数名称
18. MIME类型:multipart / from-data(固定写法)注:要么填写MIME类型,要么勾选对post使用multipart / from-data且高级→实现中选择java,二者选其一
b. BeanShell取样器
1. 可以实现跨线程组传值
2. 可以配合正则表达式提取器、JSON提取器、Xpath提取器提取出来的变量,利用setProperty函数生成函数字符串(见后文图片示例)
3. 获取时使用Property函数生成变量即可(见后文图片示例)
4. Debug Sampler(调试取样器):调试jmeter代码时使用,比如需要查看正则/json/css提取器是否提取到正确的数据
6 . 逻辑控制器:控制执行顺序
1. 如果(if)控制器
参数介绍
use status of last sample
上个取样器的使用状态:上个取样器结果成功则执行如果(if)控制器下的请求,上个取样器执行失败则不执行
Interpret Condition as Variable Expression?:选中这一项时表示:判断变量值是否等于字符串true(不区分大小写,勾选性能会比不勾选强)
勾选:(可以直接输入true或者false,但没有意义)
表达式通过jexl3或者groovy转成true或false结果,条件格式:${__jexl3(条件表达式)}
例:${__groovy(${val}==123,)}或者${__jexl3(${val}==123,)}
不勾选:表达式结果为true执行子节点,flase则不执行
例:val == 1
Evaluate for all children:如果选中这一项,在每个子结点执行前都会计算表达式
场景:如登录成功后再执行访问用户资料接口
注:用来对比的变量如果是String类型的数据,则必须用引号引起来;如果单纯只是使用变量,则可以不用
2. ForEach逻辑控制器
线程组-->添加-->逻辑控制器→ForEach控制器
输入变量前缀:如变量名为name_1、name_2、name_3、name_x···,则只输入name即可(前提是勾选了数字之前加上下划线“_”)
开始循环字段(不含):如需从1开始则填0
结束循环字段(含):如到3结束则填3
输出变量名称:给该foreach取变量名称,用时只需要${foreach变量名称}即可
3. 循环逻辑控制器
线程组-->添加-->逻辑控制器→循环控制器
循环几次循环次数填几次即可
4. while循环控制器
Condition
为空:子节点中最后一个sample执行失败才会退出循环(网上大多数说法是某次sample执行失败则退出循环,实则不准)
LAST:效果同为空
其他:条件表达式为false时退出循环
7. 前置处理器:请求之前的操作
JSR223 PreProcessor
可以导入jar包,执行java代码的方法
BeanShell PreProcessor
功能基本与JSR223一致,性能差别
8. 后置处理器:请求之后的操作
a. JSR223 PostProcessor
可以在Java平台上运行脚本语言.比如Groovy,JavaScript等
关键字:
ctx:线程上下文
prev:当前返回结果取样器
vars:读写对象
b. 正则表达式提取器
引用名称:设置参数名
正则表示式:设置需要提取的结果(通用的正则表达式语法)
.匹配任意一个字符 除了\n
*匹配前一个字符可以出现0次,1次,多次,可有可无
?匹配前一个字符出现一次或者没有出现 要么有要么没有
+匹配前一个字符至少出现一次或者多次,至少有一次
模板:如果匹配多个结果,根据模板决定提取其中的一个或多个
$-1$:表示取所有值
$0$:表示随机取值
$n$:表示取第n(n>=1)个
c. JSON提取器(见后文图片示例)
用法
$代表跟目录
如下级遇json直接.key则可以拿到value值或者["key"]
如下级遇列表(数组),则通过[索引]取值
引用名称:设置参数名
josn提取表达式:设置需要提取的结果,$.名称或者$[?],需要提取多个用英文分号隔开
匹配数量:匹配数字(0代表随机,1代表第一个,-1代表所有)
统计所有的变量值 (引用名称_ALL,注意区分大小写)
json提取器获取所有参数后,可以用foreach处理器进行循环,可以配合使用
d .Xpath提取器 (见后文图片示例)
8. 断言:判断请求在某种规则下是否正确
响应断言
断言状态码、响应体
大小断言
响应内容的字节长度
断言持续时间
判断响应时间
BeanShell断言
通过prev获取响应数据
获取响应数据:String jsonResult = prev.getResponseDataAsString();
处理响应code:if(“200“.quals(prev.getResponseCode()==false)) { Failure=true; }
9. 定时器:延迟或者间隔发送请求(执行在每一个采样器(sampler)之前,无关位置)
固定:固定延迟时间
高斯:随机延迟时间(一般用于模拟真实场景)
同步(见后文图片示例):并发时使用(一般请求数除以并发数则就是同步定时器数)
10. 配置元件:取样器配置信息
HTTP信息头管理器
在sampler中发送请求的时候,http头部信息列表会自动整合后一起发送。当http头部信息列表中的某一条信息 与sampler本身已自带的名称相同,则手动输入的信息会取代sampler自带的。访问某些有防盗链的页面时需要正确的Refer,这些情况下都需要通过HTTP Header Manager来保证发送的HTTP请求是正确的
HTTP Cookie管理器
该组件可以像浏览器一样的存储和发送Cookie,如果发送一个http请求他的响 应中包含Cookie,那么Cookie Manager就会自动地保存这些Cookie并在所有后来发送到该站点的请求中使用这些Cookie的值。也可以自己设置保存Cookie
用户自定义变量
设置常用变量;比如切换服务器,切换登录用户
CSV Data Set Config(CSV数据文件设置)
csv:逗号分隔值,一种常见的数据存储格式
语法格式(见后文图片示例):变量值1,变量值2,变量值3···, 一行代表一条数据
11. 监听器:收集测试结果
查看结果树
查看取样器的结果、请求、响应数据
如果需要对返回结果进行正则提取,可以选择查看方式为RegExp Tester,在Regular expression中测试正则表达式,查看提取结果的位置
如果需要对返回结果进行json提取,可以选择查看方式为JSON PATH Tester,在JSON PATH Tester中测试JSON表达式
聚合报告
性能指标数据
参数详解
Label:作用域内每一个http请求的名称
#Samples(样本):请求数——表示这次测试中一共发出了多少个请求,如果模拟10个用户,每个用户迭代10次,那么这里显示100
平均值:平均响应时间——默认情况下是单个 Request 的平均响应时间
中位数:50% 用户的响应时间
90%百分位:90% 用户的响应时间
95%百分位:95% 用户的响应时间
99%百分位:99% 用户的响应时间
最小值:最小响应时间
最大值:最大响应时间
异常%:错误请求数/请求总数
吞吐量:默认情况下表示每秒完成的请求数
接收 KB/sec:每秒从服务器端接收到的数据量
发送 KB/sec:每秒从服务器端接收到的数据量
线程组
setProperty和Property
json提取器
xpath提取器
同步定时器
上传csv格式文件
7、常用函数
计数器函数:
- 用户维度的计数器 c o u n t e r ( t r u e , ) ,全局计数器 {_counter(true,)}, 全局计数器 counter(true,),全局计数器{_counter(false,)}
随机数函数:
- ${_Random(1, 3,)} 1为最小值,3为最大值,都为闭区间
时间函数:
- t i m e ( , ) 无参返回时间戳, {time(,)} 无参返回时间戳, time(,)无参返回时间戳,{time(yyyy-MM-dd hh:mm:ss,)} 年-月-日 时:分:秒格式
UUID函数 :通用唯一识别码
- 使用方式:${__UUID} 生成不重复的字符串,在同一时间是唯一的
8、jmeter调试
调试取样器
jmeter + fiddle/charles/whistle
- jmeter–>http请求→高级中输入服务器名称或IP(一般是本机,localhost或者127.0.0.1),端口号(抓包工具的端口号)
- 抓包工具中过滤域名(只抓某个域名的请求)
- 执行jmeter脚本
- 抓包工具中查看请求(打断点/弱网等操作)
9、fiddle/charles/whistle自动生成jmx文件(抓包后自动生成jmeter可执行脚本)
- 抓包(不再赘述)
- 过滤需要的http请求
- 导出saz(fiddle、whistle)/ chlsj(charles)格式文件
- 将saz/chlsj文件转换为jmx文件:https://github.com/dongpengfei826153155/fiddler2jmeter
- 将导出的jmx文件导入到jmeter中,修修补补即可使用
10、非GUI操作
- 有GUI为什么还要熟悉非GUI模式操作
非GUI模式下比GUI模式消耗更少的系统资源,我建议不要只关注平均响应时间,也要关注其他重要的指标,比如说检查测试流程中的每个节点,比如线程的启动时间、每秒钟执行的事务、监听器的输出(Jemter可用的插件、生成的hmtl报告、和第三方的分析工具进行对比,结论是GUI模式下你的ramp-up更慢,因为会出现一些线程已经完成了,但是其他的进程还没有开始的情况;在非GUI模式下,ramp-up会更快,所以你有更多在线的用户,所以访问到待测系统效率更高),可以试试增加循环次数,然后观察在测试期间是怎么运行的。(官方文档翻译) - 前提:
配置好jmeter/ant环境变量(不然每次都得输入全路径或者需要cd到启动目录下命令执行) - 命令
-n 使用非GUI方式,不能单独使用,必须和-t(指定jmeter脚本)一起使用
只会生成一个log日志文件,没有报告输出
-l 生成jtl格式的报告 例:jmeter -n -t 居家干预.jmx -l D:\log.jtl
如果需要看到响应数据和请求数据的话需要修改jmeter.propties配置文件
jmeter.save.saveservice.response_data=true
jmeter.save.saveservice.samplerData=true
-e -o -e生成html报告,-o指定html报告的文件夹(文件夹必须为空,否则报错)
例:jmeter -n -t 居家干预.jmx -l result.jtl -e -o d:\result
11、使用jmeter + ant + jenkins实现持续集成
ant下载
http://ant.apache.org/bindownload.cgi
1.10.2 .zip archive 对应jdk8
解压,配置环境变量
系统环境变量中添加:D:\apache-ant-1.10.12\bin(自己的安装地址)
检查是否配置成功
ant -version
需要构建一个build.xml文件,放在jmx文件同级目录
修改jmeter.properties
jmeter.save.saveservice.output_format=xml
ant运行
jenkins todo
12、连接数据库
-
下载Mysql jdbc驱动包:https://mvnrepository.com/artifact/mysql/mysql-connector-java(版本是一个大版本就行)
-
设置JDBC Connection Configuration
Variable Name:自定义参数,在JDBC Request中会用到;
Database URL:jdbc:mysql:// 数据库IP地址:数据库端口/数据库名称;(例:jdbc:mysql://127.0.0.0:3306/mysql)如果运行报时间错误后边加上:?serverTimezone=UTC; 如果中文乱码后边加上:?useUnicode=true&characterEncoding=UTF-8
JDBC Driver Class:com.mysql.jdbc.Driver;
Username:数据库用户名;
Password:数据库密码; -
线程组下添加JDBC Request
JDBC Request中Variable Name of Poll declared in JDBC Connection Configuration填写设置的JDBC Connection Configuration中的Variable Name变量名称
-
数据库查询结果当做参数使用
JDBC Request中为variable name设置一个变量名
添加一个调试取样器(debug sample)
查看结果树中调试取样器的结果,结果的变量名就可以直接调用该变量使用
添加http请求使用该变量
13. http代理服务器
- 概念
jmeter自带的录制脚本元件,支持chrome、firefox、ie等多个浏览器 - 使用步骤
- 测试计划→ 非测试元件→ http代理服务器
- 设置端口(不能与系统运行端口冲突)
- o目标控制器:录制脚本所在的线程组
- oType:选择httpclient4即可
- requests filtering
1)包含模式:只录制包含字符的接口(前后得用.*包裹)
2)排除模式:过滤包含字符的接口(前后得用.*包裹) - 启动
- 启动后会在jmeter的bin目录下生成.crt的证书文件
- 将此证书文件导入系统(受信任的证书文件)
- 系统设置代理:端口同jmeter设置端口,ip为目标ip(一般为127.0.0.1或者localhost)
14. BeanShell
-
概念
a)BeanShell是一种轻量级的java脚本
b)Beanshell 有自己的专属语法
log、ctx 、vars、props、prev
c)Beanshell可以执行标准的java代码
java文件、class文件、jar包 -
BeanShell语法
- log
打印日志
例:log.info(“开始请求…”)
注:log.info(“只可以输入字符串”) - vars
操作jmeter变量,实际引用了JMeter线程中的局部变量容器(本质上是map)
vars.get(String key):从jmeter中获得变量值
vars.put(String key,String value):数据存到jmeter变量中 - props
操作jmeter属性,变量引用了JMeter的配置信息,可以获取Jmeter的属性,它的使用方法与vars类似,但是只能put进去String类型的值,而不能是一个对象。
props.get(String key);
props.put(String key,String value); - prev
获取前面的sample返回的信息
getResponseDataAsString():获取响应信息
getResponseCode() :获取响应code
例 :
import com.alibaba.fastjson.*;
prev.setDataEncoding(“UTF-8”);
//获取上一个请求的返回值
String response = prev.getResponseDataAsString();
log.info(response);
//将返回值转换为json对象
JSONObject jsonObject = JSONObject.parseObject(response);
//获取status
Integer status = jsonObject.get(“status”);
log.info(“status的值:” + status);
// 获取响应code
String code = prev.getResponseCode();
log.info(“响应的code:” + code);
- 断言
// 获取响应code
String code = prev.getResponseCode();
log.info(“响应的code:” + code);
if (code.equals(“200”)) {
Failure = true;
FailureMessage = “状态值有误”;
}
15. 用户参数及csv参数化
- 用户参数
前置处理器→ 用户参数
作用:定义一个变量,指定多个值,每次请求的时候会循环去取这些值。
场景:模拟一组用户登录、一个参数多种数值等等
注意:线程数可以大于值的个数,也可以小于值的个数,一般情况下等于即可(根据使用场景决定) - csv参数化
配置元件→ CSV数据文件设置
使用步骤:
1.创建.csv文件(语法格式:变量值1,变量值2,变量值3···, 一行代表一条数据)
2.添加CSV数据文件设置
1.文件名:csv文件的绝对路径
2.文件编码:默认即可:ANSI
3.变量名称:csv文件中一行有几个变量则写几个变量名称,以英文逗号相隔
4.忽略首行:true忽略csv第一行,false则从第一行开始读(第一行一般为变量名称)
5.分隔符:默认英文逗号,如果csv文件是以,相隔,则不需要改;如果以\t分割,则写\t
6.是否允许带引号:false不会读取csv中的引号,如果需要读取到csv中的引号的话则需要设置为true(如果参数中有逗号或双引号,要选为“true”)
7.遇到文件结束符再次循环:文件读取完后是否继续读取
1.例:10个线程,4行数据,true则读完4行之后继续从第一行开始读;false则读完4行后不会继续读,遇到文件结束符停止线程为true时,线程只执行4个,如为false,则执行10个,后边6个拿不到值
8.遇到文件结束符停止线程:文件读取完后是否停止线程
9.线程共享模式:作用域
场景:多个且多组参数时使用