jmeter-5-从⼊门到放弃【基础篇】
⼀、Jmeter简介:
1、简介
Jmeter 是⼀款基于Java程序开发的可视化客户端 (类似postman客户端)、具有开源、⾼可扩展性、⾼移植性、多线程框架等特点。
简单来说它就是:界⾯友好,能够快速上⼿,在任何操作系统java环境便可运⾏,基于java程序开发可⾃定义编写插件。
Jmeter业界使⽤最多的场景:
1. 服务端的性能测试 (压⼒测试、并发测试)
2. 接⼝测试、接⼝⾃动化测试 (Http、FTP、RPC、WebSocket等协议)
2、jmeter 安装
①由于是⼀个java程序,所以必备JDK,jdk1.8以上。jdk安装教程详细参考:
win:
linux:
②验证,cmd命令输⼊:java --version 及 javac
下载后直接解压。
运⾏:打开bin⽬录下的jar包,如我的解压路径(可创建快捷⽅式/超链接到桌⾯):G:\apache-jmeter-5.3\bin\ApacheJMeter.jar
可视化主界⾯:⾮常友好
⼆、Jmeter常⽤元器件
前置处理器 (⽐如:JDBC/Beam Shell预处理程序,⽤于数据准备,输⼊)
取样器(⽐如:Http请求信息)
后置处理器 (⽐如正则、json提取、JDBC/Beam Shell后置处理器)
配置元件 (⽤户⾃定义变量、CSV参数化、请求头管理器、请求默认值)
(查看请求的信息与结果,⽐如:查看结果树、聚合报告、汇总报告)
在Jmeter中元器件作⽤域是遵循上⾯的顺序,还有从上到下执⾏,如果多个层级存在同样的变量时,优先使⽤同级的(先同层级,没有到,再往上层)举例:
三、编写接⼝脚本
1、接⼝测试这⾥分为两种场景:
1. 接⼝测试既功能未提测前,基于接⼝⽂档编写脚本,进⾏的接⼝测试,同时考虑接⼝安全性的测试。
2. 接⼝⾃动化回归测试既对我们主要流程的冒烟测试,亦可细化覆盖场景(但成本⽐较⾼)
2、编写前我们需要认识 http 请求与响应的基本结构
①、接⼝请求关键参数:
1. method 请求类型:常⽤ GET、POST
2. url 接⼝的地址
3. headers 请求头
4. body 请求参数
②、接⼝响应,通常关注:响应code、响应body、耗时。
3、我们可以参考开发⼈员的接⼝⽂档进⾏编写
①接⼝来源:
1. 接⼝⽂档
2. 抓包抓取接⼝的请求来进⾏编写脚本,最好还是两者结合。(有可能会存在不⼀致)
4、获取接⼝请求与响应信息
①打开接⼝⽂档,
②抓包(web F12、抓包⼯具fiddler/Charles):
例⼦:域名,wwwblogs
2. 获取拿到的⽂章id进⼊详情,api:/gsxl/p/${id}.html
5、编写脚本例⼦
①添加-线程组
线程属性:接⼝测试以下属性,通常为1即可
1. 线程数⼀个线程相当于⼀个虚拟⽤户
2. Ramp-Up时间(秒)多少时间启动完成所有线程数,⽐如线程数10,Ramp-Up时间为20,则20秒内启动完10线程,平均就是2s启动1个线程。
3. 循环次数执⾏测试⽤例的次数
②添加-取样器-http,接⼝信息写上,博客园⾸页接⼝信息
③添加-后置处理器,提取token (常⽤:①正则②Json提取)
④添加-响应断⾔
可以响应断⾔code、⽂本包含、完全匹配。常⽤响应断⾔、json提取断⾔。
⽀持正则匹配:响应⽂本。包含或匹配模式(字符串模式是不⽀持正则)
添加查看结果树,试跑正常:
⑤添加-获取⽂章详情,取样器
接⼝地址:/gsxl/p/${id}.html
⑥添加-获取门店列表下的请求头、断⾔。
医学lambda是什么意思引⽤变量:${变量名}
⑦-添加,查看结果树
6、脚本优化:如全局变量、提搞可阅读性等
四、个⼈⼼得分享
1、jmeter接⼝测试经验分享:
编写规范分模块功能备注,适当多使⽤参数化/动态引⽤变量,如全局的域名、动态参数化关联断⾔。断⾔,多结合接⼝响应以及数据库主要字段校验(实时落库)。
前置处理器:测试数据准备,如⽂章id,我们可以通过SQL增删改查到此⽂章的详细信息,拿此⽂章id传⼊-获取⽂章详情接⼝进⾏查询,拿前置的信息与接⼝响应的主要字段进⾏断⾔。
后置处理器:对前⾯新增的测试数据进⾏还原或删除。
数据初始化:⽐如需要⽤到的账号数据,有⼀套专属进⾏初始化的脚本,这样⽅便多环境切换时快速创建所需要的数据。
接⼝⾃动化测试:快速带来的效益,适⽤于场景化关联性,如业务主流程的冒烟测试及回归测试。
小程序本地服务器搭建2、请求头必填项 (在不知道的情况下)
可利⽤抓包⼯具,去除某些请求头参数,发现body与原来正常不⼀致时则为必填。
3、数据库连接及跨线程demo
①MySQL数据库连接,得先到连接驱动,放在jmeter的lib/etx⽬录下 (其它Oracle、MongoDB也是⼀样)
如MySQL:mysql-connector-java-5.1.31.jar
jmeter操作,配置元件-添加 JDBC Connection Configuration ⽤于连接到对应数据库
取样区-添加 JDBC Request ⽤于SQL语句执⾏,如下图
Variable Name:⾃定义参数,在JDBC Request中会⽤到;
Database URL: jdbc:mysql:// 数据库IP地址:数据库端⼝/数据库名称;
JDBC Driver Class: sql.jdbc.Driver,连接时需要的驱动;
Username:数据库⽤户名;
Password:数据库密码;
使⽤ BeanShell 将变量跨线程
4、常⽤函数
__Random:随机数 ${__Random(1,10,)}
__time:当前时间 ${__time(yyyy-MM-dd HH:mm:ss,)}
等等...根据实际需求使⽤
这⾥还有很多:
5、CSV参数化
可以⽤例ddt数据驱动接⼝测试,将测试接⼝等数据填写⼦⽂件⾥⾯,让CSV读取后参数化引⽤变量进⾏循环请求。
6、Jmeter⾃定义插件-请求参数加签加密
1. 如果公司后端是java很好办,开发的代码把代码复制过来。
2. 如果公司后端不是java,那就要了解它的加密规则,⾃⼰写⼀个java程序。
3. 拿到代码在⾃⼰本地调试,最终打包成jar包,放置lib/ext⽬录下即可,BeanShell引⽤,如下列⼦。
①拿到代码,创建maven项⽬,粘贴到你的class类,pom导⼊依赖,调试成功后打jar包,放置lib/ext⽬录下即可
7、持续集成-流程图
欢迎来⼤家QQ交流⼀起学习:482713805
附上上述所⽤到的jmx脚本:
CSV:
id,exp
14671963,啊这...2-get/post请求区别,来给你看看post请求url中传参
14993497,jmeter-5-从⼊门到放弃【基础篇】
13950531,python-51-MySQLdb查询返回dict格式
jmx:
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.3">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="测试计划" enabled="true">
<stringProp name="TestPlanments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="arDown_on_shutdown">true</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">true</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="⽤户定义的变量" enabled="true"> <collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath">C:\Users\PPL\Desktop\ppl.jar</stringProp>
</TestPlan>
<hashTree>
<Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="环境变量" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="id" elementType="Argument">
<stringProp name="Argument.name">id</stringProp>
<stringProp name="Argument.value">13694071</stringProp>
vue生命周期图<stringProp name="Argument.desc">全局⽂章id</stringProp>
<stringProp name="adata">=</stringProp>
</elementProp>
<elementProp name="http" elementType="Argument">
<stringProp name="Argument.name">http</stringProp>
<stringProp name="Argument.value">https</stringProp>
<stringProp name="Argument.desc">环境协议</stringProp>
<stringProp name="adata">=</stringProp>
</elementProp>
<elementProp name="url" elementType="Argument">
<stringProp name="Argument.name">url</stringProp>
<stringProp name="Argument.value">wwwblogs</stringProp>
<stringProp name="adata">=</stringProp>
<stringProp name="Argument.desc">环境域名</stringProp>
</elementProp>
<hashTree/>
<ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="请求默认值" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="⽤户定义的变量" enabled="true"> <collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain">${url}</stringProp>
<stringProp name="HTTPSampler.port"></stringProp>
<stringProp name="HTTPSampler.protocol">${http}</stringProp>
<stringProp name="tEncoding"></stringProp>
<stringProp name="HTTPSampler.path"></stringProp>
<stringProp name="urrentPool">6</stringProp>
<stringProp name="t_timeout"></stringProp>
<stringProp name="sponse_timeout"></stringProp>
mysql入门基础教程</ConfigTestElement>
<hashTree/>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="测试-1-线程组" enabled="false">
<stringProp name="_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="循环控制器" enabled="true"> <boolProp name="inue_forever">false</boolProp>
<stringProp name="LoopController.loops">1</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">1</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
</ThreadGroup>
<hashTree>
<GenericController guiclass="LogicControllerGui" testclass="GenericController" testname="博客园⾸页" enabled="true"/>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="博客园⾸页" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgume
ntsPanel" testclass="Arguments" testname="⽤户定义的变量" enabled="true"> <collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain"></stringProp>
<stringProp name="HTTPSampler.port"></stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="tEncoding"></stringProp>
<stringProp name="HTTPSampler.path">/gsxl</stringProp>
<stringProp name="hod">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="bedded_url_re"></stringProp>
<stringProp name="t_timeout"></stringProp>
<stringProp name="sponse_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="响应断⾔" enabled="true">
<collectionProp name="st_strings">
<stringProp name="1705342405">⼴深-⼩龙</stringProp>
</collectionProp>
<stringProp name="Assertion.custom_message"></stringProp>
<stringProp name="st_field"&sponse_data</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="st_type">2</intProp>
</ResponseAssertion>
易语言代码大全及示例<hashTree/>
<RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="正则提取⾸页⽂章id:id_1" enabled="true">
<stringProp name="RegexExtractor.useHeaders">false</stringProp>
<stringProp name="fname">id_1</stringProp>
<stringProp name="">p/(.+?).html</stringProp>
<stringProp name="plate">$1$</stringProp>
<stringProp name="RegexExtractor.default">id_1 Error</stringProp>
<stringProp name="RegexExtractor.match_number">1</stringProp>
</RegexExtractor>
<hashTree/>
<BeanShellPostProcessor guiclass="TestBeanGUI" testclass="BeanShellPostProcessor" testname="BeanShell 后置处理程序-将⽂章id设置为所有线程组共享" enabled="true"> <stringProp name="filename"></stringProp>
<stringProp name="parameters"></stringProp>
<boolProp name="resetInterpreter">false</boolProp>
<stringProp name="script">String id = ("id_1");
props.put("id_1", id);</stringProp>
</BeanShellPostProcessor>
<hashTree/>
</hashTree>
</hashTree>
<GenericController guiclass="LogicControllerGui" testclass="GenericController" testname="获取⽂章详情" enabled="true"/>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="获取id为${id}⽂章内容(正则提取关联的id)" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="⽤户定义的变量" enabled="true"> <collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain"></stringProp>
<stringProp name="HTTPSampler.port"></stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="tEncoding"></stringProp>
<stringProp name="HTTPSampler.path">/gsxl/p/${id_1}.html</stringProp>
<stringProp name="hod">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="bedded_url_re"></stringProp>
<stringProp name="t_timeout"></stringProp>
<stringProp name="sponse_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="响应断⾔" enabled="true">
<collectionProp name="st_strings">
<stringProp name="-1601435010">啊这...2-get/post请求区别,来给你看看post请求url中传参 - ⼴深-⼩龙 - 博客园</stringProp>
<stringProp name="0"></stringProp>
</collectionProp>
<stringProp name="Assertion.custom_message"></stringProp>
<stringProp name="st_field"&sponse_data</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="st_type">2</intProp>
</ResponseAssertion>
<hashTree/>
</hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="获取id为${id}⽂章内容(全局变量关联的id)-1" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="⽤户定义的变量" enabled="true"> <collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain"></stringProp>abap
<stringProp name="HTTPSampler.port"></stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="tEncoding"></stringProp>
<stringProp name="HTTPSampler.path">/gsxl/p/${id}.html</stringProp>
<stringProp name="hod">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="bedded_url_re"></stringProp>
<stringProp name="t_timeout"></stringProp>
<stringProp name="sponse_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="响应断⾔" enabled="true">
<collectionProp name="st_strings">
<stringProp name="-333710551">title: 'jmeter-4-linux下环境搭建 jmeter+ant+docker-jenkins,持续集成测试完成</stringProp>
</collectionProp>
<stringProp name="Assertion.custom_message"></stringProp>
<stringProp name="st_field"&sponse_data</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="st_type">2</intProp>
</ResponseAssertion>
<hashTree/>
</hashTree>
</hashTree>
</hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="获取⽂章详情-2-线程组" enabled="false">
<stringProp name="_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="循环控制器" enabled="true"> <boolProp name="inue_forever">false</boolProp>
<stringProp name="LoopController.loops">1</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">1</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
</ThreadGroup>
<hashTree>
<GenericController guiclass="LogicControllerGui" testclass="GenericController" testname="获取⽂章详情" enabled="true"/>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="获取id为${id}⽂章内容(全局变量关联的id)-2" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="⽤户定义的变量" enabled="true"> <collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain"></stringProp>
<stringProp name="HTTPSampler.port"></stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="tEncoding"></stringProp>
<stringProp name="HTTPSampler.path">/gsxl/p/${id}.html</stringProp>
<stringProp name="hod">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="bedded_url_re"></stringProp>
<stringProp name="t_timeout"></stringProp>
<stringProp name="sponse_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="响应断⾔" enabled="true">
<collectionProp name="st_strings">
<stringProp name="-333710551">title: 'jmeter-4-linux下环境搭建 jmeter+ant+docker-jenkins,持续集成测试完成</stringProp>
</collectionProp>
<stringProp name="Assertion.custom_message"></stringProp>
<stringProp name="st_field"&sponse_data</stringProp>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论