一、Jmeter简介与安装
1. Jemter是什么
- Apache JMeter 是Apache组织的开放源代码项目,是一个100%纯Java桌面应用,用于接口、性能测试。
- 它最初被设计用于Web/HTTP应用测试,但后来扩展到其它测试领域。
- 它可以用于HTTP和SQL数据库(使用JDBC)压测,可以用来模拟对服务器或者网络系统加以重负荷以测试它的抵抗力,或者用来分析不同负荷类型下的所有运行情况。
- 它也提供了一个可视化界面(GUI)用来定制数据显示,测试同步及测试的创建和执行。
2. 为什么使用Jmeter
- 开源免费,基于Java编写,可集成到其他系统可拓展各个功能插件
- 支持接口测试,压力测试(分布式测试)等多种测试类型,支持录制回放,入门简单
- 相较于自己编写框架或其他开源工具,有较为完善的UI界面,便于接口调试
- 多平台支持,可在Linux,Windows,Mac上运行
- 提供多种报表数据图形展示
3. Jmeter的下载及安装
- 1、快速下载:https://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/
- 2、文档地址:http://jmeter.apache.org/usermanual/get-started.html
- 3、需要安装JDK8(或更新),建议安装JDK环境
- 4、免安装,解压即可使用,直接使用即可。双击 JMETER_HOME/bin/jmeter.bat 启动
4. Jmeter的目录文件介绍
- bin: 核心可执行文件,包含配置
- jmeter.bat: windows启动文件
- jmeter-server.bat:windows下启动负载生成器(肉鸡)服务文件
- jmeter: mac或者Liunx启动文件
- jmeter-server:mac或者Liunx下启动负载生成器服务文件
- jmeter.properties: 核心配置文件
- 设置默认语言:language=zh_CN
- 配置远程肉鸡IP和端口(服务器):remote_hosts=123.123.123.132:1099,234.234.234.234:1099
- 肉鸡上配置:server_port=1099
- 输出报告的配置,480行左右
- extras:插件拓展的包
- Lib:核心的依赖包
- Ext:核心包,协议包
- Junit:单元测试包
5. Jmeter工作原理
向服务器发送请求到接收相应的过程。
二、Jmeter的常用组件
1. 组件介绍
- 测试计划(Test Plan): 使用 JMeter 进行测试的起点,它是其它 JMeter 测试元件的容器
- 线程组(Thread Group):代表一定数量的并发用户,它可以用来模拟并发用户发送请求
- 采样器(sampler):定义实际的请求内容,被线程组包含,我们主要用HTTP请求
- 监听器(Listener) :包含查看结果树及聚合报告等图形化显示结果
- 逻辑控制器(Logic Controller):逻辑判断功能,如if、for等语句控制
- 断言(Assertions) :包含响应断言断言、xml断言等
- 配置元件(Config Element):主要包括参数化配置、JDBC配置等
- 前置处理器(Pre Processors)和后置处理器(Post Processors)
- 定时器(Timer):用于操作之间设置等待时间
2. 测试计划
打开Jmeter即显示测试计划,测试计划用来描述一个测试(性能测试或者接口测试),包含与本次性能测试所有相关的功能,即该性能测试的所有内容是于基于一个计划的。
- 用户定义的变量
一般添加一些系统常用的配置;如果测试过程中需要切换环境、配置,一般不建议在测试计划上添加变量,因为不方便启用和禁用,一般是直接添加用户自定义变量组件 - 独立运行每个线程组
用于控制测试计划中的多个线程组的执行顺序,如果勾选了,可以保证按照顺序依次执行;不然则会交替执行 - Run tearDown Thread Groups after shutdown of main threads
开启之后,当线程组遇到错误停止时,会执行tearDown线程组;不然不会执行 - 函数测试模式(Functional Testing)
如果选中了此选项,监听组件如“查看结果树”配置了保存到一个文件中,那么jmeter会将每次的请求结果保存到文件中。一般不建议勾选
3. 线程组
常见概念:
- 进程: 正在运行的程序 = 程序启动,进程创建,程序退出,进程释放
- 线程: 进程中的执行线索 = 游戏中,能动的角色 或者 迅雷每一部电影下载,底层都对应一个线程实现
- 线程组: 对线程按照性质归类分组 = 比如: 植物大战僵尸,划分三组能量组、攻击组、破坏组
- 层级关系: 进程 > 线程组 > 线程 (一个进程包含多个线程组,一个线程组包含多个线程)
- 并发执行: 程序中的多个线程同时执行 = 多部电影下载 = 线程结束顺序与启动顺序不一定一致
- 顺序执行: 程序中的多个线程按照先后顺序依次执行 = 电影先下载完毕,然后再播放 = 线程结束顺序与启动顺序一致
线程组设置:
线程组相当于有多个用户,同时去执行相同的一批次任务。每个线程之间都是隔离的,互不影响的。一个线程的执行过程中,操作的变量,不会影响其他线程的变量值。
测试计划右键添加->threads->线程组(控制总体并发)
- 线程数
虚拟用户数,一个虚拟用户占用一个线程 - 准备时长
全部线程启动的时长,比如100个线程,20秒,则表示20秒内100个线程都要启动完成,每秒启动5个线程 - 循环次数
每个线程发送的次数,假如值为5,100个线程,则会发送500次请求,可以勾选永远循环
4. 采样器
- 采样器定义实际的请求内容,被线程组包含,我们主要讲HTTP请求及JDBC Request
- 线程组->添加-> Sampler(采样器) -> Http
采样器参数配置:
- 名称:采样器名称
- 注释:对这个采样器的描述
- web服务器:默认协议是http、默认端口是80
- 服务器名称或IP :请求的目标服务器名称或IP地址
- 路径:服务器资源的路径
5. 监听器
- 监听器包含查看结果树及聚合报告等图形化显示结果,我们主要讲查看结果树及聚合报告
- 线程组->添加->监听器(Listener)-> 查看结果树
6. 断言
- 断言用于检查测试中得到的响应(response)数据等是否符合预期,断言用以保证接口(性能)测试过程中的数据交互是否与预期一致
a、响应断言
- 线程组 -> 添加 -> 断言 -> 响应断言
- apply to(应用范围):
Main sample only: 仅当前父取样器 进行断言 - 要测试的响应字段
响应文本:即响应的数据,比如字符串、json等文本
响应代码:http的响应状态码,比如200,302,404这些
响应信息:http响应代码对应的响应信息,例如:OK, Found
Response Header: 响应头 - 模式匹配规则:
- 包括:包含在里面就成功,支持正则匹配
- 匹配:响应内容完全匹配,支持正则匹配
- equals:完全匹配,不支持正则匹配
- substring:包括子串就成功,不支持正则匹配
b、Json断言
- 线程组 -> 添加 -> 断言 -> json断言
{"avatar_large": "https://cdn.v2ex.com/navatar/6cdd/60ea/184_large.png?m=1587133817", "name": "apple"}
- Assert json path exists:$.name
[{"avatar_large": "https://cdn.v2ex.com/navatar/6cdd/60ea/184_large.png?m=1587133817", "name": "apple"},
{"avatar_large": "https://cdn.v2ex.com/navatar/6cdd/60ea/184_large.png?m=1587133817", "name": "python"}]
- Assert json path exists:$[0].name
{"avatar_large": [{"url":https://cdn.v2ex.com/navatar/6cdd/60ea/184_large.png?m=1587133817", "name": "apple"},{"url": "https://cdn.v2ex.com/navatar/6cdd/60ea/184_large.png?m=1587133817", "name": "python"}]}
-
Assert json path exists:$.avatar_large[0].name
- additonally assert value:勾选后可以在下方文本框中添加断言之
- match as regular expression:勾选后,文本框支持正则表达式
7. 参数化:
Jmeter提供的参数化方式:
- 测试计划用户定义变量参数化
- 用户自定义变量参数化
- 用户变量
- CSV文件数据参数化(文本文件)
- 函数助手
7.1 测试计划用户定义变量参数化
测试计划中设置的参数,可以用作全局变量使用
7.2 用户定义变量参数化
很多变量在全局中都有使用,或者测试数据更改,可以在一处定义,四处使用,比如登录用户名、密码,服务器地址、端口等
与测试计划的用户变量参数化功能一致,不管放在测试计划下,还是某一个线程组下,参数都是可用的,可以跨线程组使用。
操作步骤:
- 线程组->add -> Config Element(配置原件)-> User Definde Variable(用户定义的变量)
- 引用方式${XXX},在接口中变量中使用
- 查看结果树验证参数化是否成功
7.3 用户参数
- 如果设置用户参数是测试计划级别的,所有的线程组内的请求都可以使用
- 如果设置用户参数是线程组级别的,只能该线程组内的请求使用
操作步骤:
- 线程组->add -> 前置处理器-> 用户参数
- 添加参数及用户
- 引用方式${XXX},在接口中变量中使用
- 查看结果树验证参数化是否成功
7.4 csv文件数据参数化
从数据库中导出的真实在线数据在csv文件(或txt)中,作为参数化的数据源,模拟大量数据
操作步骤:
- 线程组->add -> Config Element(配置原件)-> CSV data set config (CSV数据文件设置)
- 引用方式${XXX},在接口中变量中使用
- 查看结果树验证参数化是否成功
7.5 函数助手
- 通过函数助手生成,csv文件数据调用参数,直接使用即可,只能是多个线程执行才能循环拿数据,
- 并且是线程组共享数据。
8. 第一个接口用例
- 主要看过程
- 创建一个线程组包含user、info、login三个请求
- users请求里面添加相应文本断言、相应代码断言,添加查看结果树、断言结果
- 对info请求添加查看结果树
- 对login请求添加json断言、csv文件数据参数(参数化)
- 对线程组添加聚合报告和查看结果树
9. 查看结果
如图可以查看取样器结果,请求体和请求头,响应头和响应体的结果
如下图,为参数化文件中读取到的数据
左边显示为绿色的勾,表示预期结果与实际结果一致,通过
聚合报告输出
三、Jmeter进行接口测试
1. 进行HTTP/HTTPs的get接口测试
- 见上面第8点
在测试https协议的时候,如果遇到jmeter不支持该网站的https协议,需要将该网站的证书加入到jmeter:
- 从网站上导出证书到本地
- cmd下执行指令:keytool -import -alias test -file e:\v2excom.crt -keystore e:\hellocj.keystore
- Jmeter中导入生成的keystore文件
2. 进行HTTP/HTTPs的post接口测试
- 见上面第8点
3. 进行JDBC请求
操作步骤
-
测试计划->下方浏览添加jdbc的jar包到classpath: mysql-connector-java-5.1.30.jar
-
JDBC request->add -> config element -> JDBC connection configuration
-
JDBC连接设置各项参数
Variable Name:数据库连接池的名称,我们可以有多个jdbc connection configuration,每个可以起个不同的名称,在jdbc request中可以通过这个名称选择合适的连接池进行使用。 Max Number of connections : 最大连接数 MAX wait :最大等待时间 Auto Commit: 是否自动提交事务 DataBase URL : 数据库连接地址 jdbc:mysql://127.0.0.1:3306/XX JDBC Driver Class : 数据库驱动,选择对应的mysql username:数据库用户名 password:数据库密码
mysql数据库接口测试:
- update statement及select statement :
Select Statement:仅支持测试select语句,并且一次只能测试一条
Update Statement:支持测试非select语句(增删改),并且支持测试多条;若其中夹杂select语句,自动忽略;若第一条语句为select语句,报错;除了最后一句不需要分号外,其他的要加分号
Callable Statement:用于存储过程和方法,只要语法正确,任何语句,再多的条数都能支持
- prepared update statement及prepared select statement
prepared Select Statement:仅支持测试select语句,使用?进行占位
prepared Update Statement:支持测试非select语句(增删改),使用?进行占位
注意:
需要结合parameter values及parameter types进行使用
4、进行ftp请求的测试
xampp下启动filezilla服务,并配置ftp服务器:
- 添加一个用户名:allen
- 为用户添加密码:123456
- 为用户添加一个共享文件夹:选择本机某一文件夹即可,尽量不要有中文的路径
- 为文件夹设置访问权限:增删改查,勾选即可
- 保存退出服务器设置
- 打开我的电脑,在路径栏中输入:ftp://127.0.0.1/,弹出共享的文件夹即可
ftp下载接口
- 服务器名称或IP:192.168.173.6
- Remote File(填共享文件夹中有的文件):/aa.json
- Local File(填本地的路径及下载文件副本名称):C:/jmeter/ab.json
- 勾选:get(RETR)
- 用户名:yang
- 密码:123456
ftp上传接口 - 服务器名称或IP:192.168.173.6
- Remote File(填服务器的路径及上传文件副本名称):/yang.json
- Local File(填本地文件名称):C:\jmeter\aaa.json
- 勾选:put(stor)
- 勾选:use binary mode(不然上传超文本文件会错误)
- 用户名:yang
- 密码:123456
四、脚本录制
一般采用两种录制方式:Jmeter代理录制及第三方工具BadBoy录制
- 通过BadBoy录制, Badboy是一款免费WEB自动化测试工具,简单易用但是因为采用的是内置的浏览器进行的录制,而内置的浏览器的内核是IE内核,可能会因为浏览器内核兼容性导致不能录制
- Jmeter自带的http代理服务器录制,核心原理是自动抓包自动解包的过程,在客户端进行代理配置,使得客户端通过Jmeter代理服务去访问被测服务器。
如果客户端是PC机:则可以通过ie选项来进行配置 如果客户端是移动设备:则可以通过wlan高级设置进行代理 一般为了使脚本更加简洁,需要过滤静态资源:.*\.js .*\.jpg等
1. Badboy录制脚本
JMeter录制脚本有多种方法,其中最常见的方法是用第三方工具badboy录制,另外还有JMeter自身设置(Http代理服务器+IE浏览器设置)来录制脚本,但这种方法录制出来的脚本比较多且比较乱,个人不太喜欢,一般常见Badboy进行录制,下面来介绍下Badbody录制。
注:使用JMeter的代理或是BadBoy进行录制的时候,特别是JMeter代理的时候,操作不能太快,不然容易造成录制失败
Step01:打开badboy工具,在地址栏目中输入被测试项目的地址(badboy正常状态下是录制状态,为红色按钮)
Step02:录制完成后,点击工具栏旁边黑色按钮,结束录制
step03:File->export to Jmeter
Step04:Jmeter中打开->选择badboy导出的jmx文件
Step05:编辑并优化脚本
2. 代理录制
Step01:在Jmeter中测试计划中添加线程组及HTTP代理服务器,测试计划->添加->非测试元件,配置浏览器IE选项,JMeter HTTP代理服务器的端口和浏览器设置的端口要一致
Step02:在Requests Filtering 中输入过滤的请求:.*\.jpg,.*\.js,.*\.css 输入此3个表示不录制有此后缀的请求,可以精简脚本
Step03:Jmeter添加线程组->HTTP请求默认值,并设置默认数据
Step04:Jmeter添加线程组->配置元件,分别添加HTTP Cookie 管理器,该元件会保存服务器发到客户端的sessionId到cookie中,此处需要手动添加。
Step05:启动HTTP代理,就可以在浏览器中进行被试系统的访问操作了,对应的操作脚本会记录在Jmeter中。
Step06:再添加相应的监听器就可以回放并查看回放记录了
五、Jmeter non GUI模式运行
Jmeter提供两种场景运行方式,一种是GUI(视窗运行)方式,另外一种是非GUI方式运行(命令窗口)。
-
Jmeter非GUI界面,压测参数讲解:
- -h 帮助
- -n 非GUI模式
- -t 指定要运行的 JMeter 测试脚本文件
- -l 记录结果的文件 每次运行之前 要确保之前没有运行过,即xxx.jtl不存在,不然报错
- -e 在脚本运行结束后生成html报告
- -o 用于存放html报告的目录(目录要为空,不然报错)
- -r Jmter.properties文件中指定的所有远程服务器
要求: 选择可运行的信互登录及文件上传接口脚本在非GUI模式下运行,并将运行结果文件.jtl文件保存到E:\result\jtl中;将图形化HTML报告保存到E:\result\html中。 CMD命令行中执行下面指令即可: jmeter -n -t D:\result\xinhu.jmx -l E:\result\jtl\result.jtl -e -o E:\result\html
六、Jmeter+Ant+Jenkins持续集成
Jmeter与ant集成:
- 下载: http://ant.apache.org/bindownload.cgi
- ant环境变量:E:\apache-ant-1.9.7\bin
- 将JMeter的extras目录中ant-jmeter-1.1.1.jar包拷贝至ant安装目录下的lib目录中
- 修改JMeter的bin目录下jmeter.properties文件的配置:jmeter.save.saveservice.output_format=xml
- 任意新建一个脚本存放目录:E:\apache-jmeter-2.13\AutoTest、报告存放目录report
- 在E:\apache-jmeter-2.13\AutoTest目录下,新建一个build.xml文件(ant自动构建文件)
<?xml version="1.0" encoding="GB2312"?>
<project name="ant-jmeter-test" default="run" basedir=".">
<!-- 需要改成自己本地的 Jmeter 目录-->
<property name="jmeter.home" value="E:\apache-jmeter-2.13" />
<property name="report.title" value="SZSG_三国"/>
<!-- jmeter生成jtl格式的结果报告的路径-->
<property name="jmeter.result.jtl.dir" value="E:\apache-jmeter-2.13\AutoTest\report" />
<!-- jmeter生成html格式的结果报告的路径-->
<property name="jmeter.result.html.dir" value="E:\apache-jmeter-2.13\AutoTest\report" />
<!-- 生成的报告的前缀-->
<property name="ReportName" value="thinkive" />
<property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}.jtl" />
<property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}.html" />
<target name="run">
<antcall target="test" />
<antcall target="report" />
</target>
<target name="test">
<taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask" />
<jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}">
<!-- 声明要运行的脚本"*.jmx"指包含此目录下的所有jmeter脚本-->
<testplans dir="E:\apache-jmeter-2.13\AutoTest" includes="Login_test.jmx" />
<property name="jmeter.save.saveservice.output_format" value="xml"/>
</jmeter>
</target>
<path id="xslt.classpath">
<fileset dir="${jmeter.home}/lib" includes="xalan*.jar"/>
<fileset dir="${jmeter.home}/lib" includes="serializer*.jar"/>
</path>
<target name="report">
<tstamp> <format property="report.datestamp" pattern="yyyy/MM/dd HH:mm" /></tstamp>
<xslt
classpathref="xslt.classpath"
force="true"
in="${jmeter.result.jtlName}"
out="${jmeter.result.htmlName}"
style="${jmeter.home}/extras/jmeter-results-detail-report_21.xsl">
<param name="dateReport" expression="${report.datestamp}"/>
<param name="titleReport" expression="${report.title}:${report.datestamp}"/>
</xslt>
<!-- 因为上面生成报告的时候,不会将相关的图片也一起拷贝至目标目录,所以,需要手动拷贝 -->
<copy todir="${jmeter.result.html.dir}">
<fileset dir="${jmeter.home}/extras">
<include name="collapse.png" />
<include name="expand.png" />
</fileset>
</copy>
</target>
</project>
- cmd进入脚本目录:E:\apache-jmeter-2.13\AutoTest。(即build.xml所在的目录),输入:ant 或 ant run(run为build.xml中的task名),执行结果及报告如下:
ant与Jenkins集成:
- Jenkins中添加Ant的插件并在环境变量中添加Ant的bin目录
- Jenkins新建一个自由风格的项目:
- 配置构建任务,选择构建类型为invoke ant,设置如下,保存退出设置界面:
- 构建任务,进入到设置的项目
- 点击上一步的构建结果,查看控制台显示结果
- 查看输出的报告:在上文E:\3-Learning\04-QF201903\jmeter\AntReport目录下可以查看任务运行的jtl及html报告结果。