原因:打开错误文件
解决办法:进入jemeter安装文件,bin-》jemeter.bat,双击后出现两个界面,cmd文件打开后不能关掉(关掉后就不能使用jemeter),出现testplan就证明可以正常使用。
原因:配置元件的优先级最高,所以HTTP请求默认值为准】
解决办法一:分组,将不同的请求分成多组线程,将配置元件的值设置为对应的数据
解决办法二:将不同的请求使用简单控制器(simple controller)来分组,在每个简单控制器下加入配置元件,可以实现同样效果
> Not able to find Java executable or version. Please check your Java
> installation. errorlevel=2 请按任意键继续. . .
问题原因:以前的旧版或多版本的java.exe文件没有删除掉所导致的,删除即可以正常打开
解决办法:操作步骤可参考-----安装了jdk,在命令行界面显示javac不是内部或外部命令如何解决这篇文章
解决办法:修改jmeter的配置文件(位置:安装文件下的bin文件夹中)jmeter.properties
注:需要将前面的#号删掉才能起作用
jmeter.toolbar.icons.size=32x32----上方功能区图标大小
jmeter.tree.icons.size=24x24---左侧视图区图标大小
#调整JMeter内容区的编辑字体
jsyntaxtextarea.font.family=consolas #默认Hack,太难看,使用经典的consolas
jsyntaxtextarea.font.size=18 #这两个配置项必须同时设置才有效
现象:修改后导致图标非常大,但是视图区的字体大小不变,最终导致字体挤压看不清楚
原因:由于屏幕的分辨率是1920,但是jmeter软件可能不适用这种分辨率,导致视图区的字体太小了
解决办法:修改分辨率为1366X768 更改文本为100%,即可正常显示
前提:jmeter中有以下jar包,一般下载会自带
beanshell的代码:
import org.apache.commons.codec;
String resp_data = vars.get("jiamidata");
log.info("待加密的字符串为:"+resp_data);
log.info("------------开始解密-------------------");
org.apache.commons.codec.binary.Base64 base64=new org.apache.commons.codec.binary.Base64();
String s=new String(base64.decode(resp_data),"UTF-8");
vars.put("requ_str",s);
log.info("解密后的值------->>"+s);
log.info("------------解密结束-------------------");
可以使用beanshell sampler进行调试,点击右上角小叹号可以进行打印日志
显然,这种方式并没有成功,但是目前不确定原因
原因:网上说是可能缺少包、jar包冲突、Java SDK环境变量或jemeter环境变量存在问题。
解决办法一: 更换jemeter主题,可能需要重启电脑(对我没用,大家可以依次尝试):
解决办法二:JDK和jemeter不匹配,我安装的JDK是16,现在更换为11(只需将原有JDK删掉,重新安装JDK,不用改变jemeter任何设置),重启jemeter就可以保存了。
应用场景:性能测试中模拟多个用户访问系统,需要不同用户,不同密码,故将用户名、用户密码进行参数化进行测试
数据文件格式:支持csv以及txt文件
原理:根据设置的参数、分隔符等读取文件内的数据,将数据与定义的变量关联,在后续的请求中进行引用
基础字段说明:名称、注释根据自己的需求定义即可
Filename:保存数据的文件路径,支持相对路径或者绝对路径
注:相对路径后面需要加上/bin(E:\auto_test/bin)----调通后试下
File Encoding:文件编码方式;文件类型不同,设置的文件编码不同,默认为ANSI
csv:GBK
txt:utf-8
Variable Names:参数名称
如果有多个参数时,多个参数名称中间的分隔符需要与文件内分隔符、Delimitet分隔符保持一致,默认使用英文逗号。
如果参数名称数量多于文件内数据,则多出的参数名称取不到值;如果参数名称少于文件内数据,则文件内数据无法引用
Delimitet:分隔符,即数据文件内分隔不同数据的符号
Allow Quoated data?:数据是否需要加上引号,True为数据必须要用引号引起来
Recycle on EOF :遇到文件结束符时,是否需要从文件开始再次循环,true为再次循环
Stop Thread on EOF :在上一个参数的基础上,循环读取到文件结尾后,线程是否结束,true为结束,默认为true
Sharing Mode:参数文件共享模式,有三个设置,说明如下:
All threads:参数文件对所有线程共享,即同一计划下的所有线程组
Current thread group:只对当前线程组中的线程共享。
Current thread:仅当前线程获取。
注:在读取txt文件时,可能存在设置编码格式为utf-8,依然乱码的情况,可以重新编辑,保存文件时将文件的编码格式改为utf-8就可以
可能原因1:部分取样器中存在错误,如取样器下的JSON提取器或正则表达式提取器存在错误
方法:运行后查看jmeter的日志,右上角黄色叹号标识,查看报错原因
修改后可以单独跑对应线程组,验证是否修改正确
场景:实际应用中部分功能存在,将页面数据导出为文档
此时需要:1、校验文档导出成功;2、校验文档导出数据
尝试方法一:使用响应断言,断言返回码为200,即导出成功
缺陷:当导出文档内容为空,返回状态码依然为200,并不能验证到测试点2
尝试方法二:使用响应断言,断言内容包含XXX(文档中应当导出的字段)
原因:下载相关接口返回数据,当查看格式为Text,则为乱码;
所以可以通过将返回数据改成Document格式,验证返回内容是否包含文档中导出字段取验证导出文文档是否有数据。
注:使用中文去判断,需要导入jar包:**tika-app-1.17.jar**
文件需要放入jmeter-lib中
缺陷:当前生效是在GUI模式下,如果远程去跑,可能会存在警告之类的信息
023-10-17 14:50:52,143 ERROR o.a.j.e.j.j.JSONPostProcessor: Number of JSON Path variables must match number of default values and json-path expressions, check you use separator ';' if you have many values
java.lang.IllegalArgumentException: Mismatch between number of variables, json expressions and default values
at org.apache.jmeter.extractor.json.jsonpath.JSONPostProcessor.process(JSONPostProcessor.java:93) ~[ApacheJMeter_components.jar:4.0 r1823414]
at org.apache.jmeter.threads.JMeterThread.runPostProcessors(JMeterThread.java:839) ~[ApacheJMeter_core.jar:4.0 r1823414]
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:516) ~[ApacheJMeter_core.jar:4.0 r1823414]
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:416) [ApacheJMeter_core.jar:4.0 r1823414]
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:250) [ApacheJMeter_core.jar:4.0 r1823414]
解决方法:找到对应JSON提取器,将提取变量的数量和默认值的数量保持一致即可。
尝试方法一(失败):仔细观察url、传参、格式是否一致,发现当前线程组下没有加Content-Type,添加后依然报相同错误
原因:JMETER和postman不一样,postman中Content-Type是自动添加的,但是JMETER需要手动添加到请求头信息管理器中
尝试方法二(成功):使用相同数据(url、参数、请求头信息)在postman中调用,可以调通,也就是说数据没有问题,排查发现取样器中没有加入token,加入全局化的token,再次访问,可以访问成功。
原因:options请求是预检请求,只是用来验证是否接收请求,如果接收,则后续会继续发送请求
options详细分析:
作用:检查某url在服务器中支持的请求方法。
应用场景:出于安全性的考虑,在发起跨域请求时,若符合**复杂请求**,则浏览器会在正式请求前发送options请求。
原理:跨域共享标准规范要求:对可能对服务器数据产生副作用的请求方法,浏览器需先使用OPTIONS方法发起预检请求(相同URL,但是请求方法为OPTIONS),确认服务端是否允许该请求方法;当服务器允许时,则使用相同的URL,采取服务端允许的请求方法,去再次请求。
简单请求定义:不会触发CORS预检请求的请求
简单请求范围:
- 请求方式为get、head、post
- 设置规范集合范围之内的请求头字段:Accept、Accept-Language、Content-Language、
-
复杂请求定义:触发CORS预检请求的请求
023-10-19 17:36:20,235 ERROR o.a.j.f.Jexl3Function: An error occurred while evaluating the expression "${taskid}==null"
org.apache.commons.jexl3.JexlException$Parsing: @1:2 parsing error in '{'
at org.apache.commons.jexl3.JexlEngine.createExpression(JexlEngine.java:304) ~[commons-jexl3-3.1.jar:3.1]
at org.apache.jmeter.functions.Jexl3Function.execute(Jexl3Function.java:94) [ApacheJMeter_functions.jar:4.0 r1823414]
at org.apache.jmeter.engine.util.CompoundVariable.execute(CompoundVariable.java:137) [ApacheJMeter_core.jar:4.0 r1823414]
at org.apache.jmeter.engine.util.CompoundVariable.execute(CompoundVariable.java:112) [ApacheJMeter_core.jar:4.0 r1823414]
at org.apache.jmeter.functions.gui.FunctionHelper.actionPerformed(FunctionHelper.java:200) [ApacheJMeter_core.jar:4.0 r1823414]
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022) [?:1.8.0_92]
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348) [?:1.8.0_92]
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) [?:1.8.0_92]
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) [?:1.8.0_92]
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252) [?:1.8.0_92]
at java.awt.Component.processMouseEvent(Component.java:6533) [?:1.8.0_92]
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324) [?:1.8.0_92]
at java.awt.Component.processEvent(Component.java:6298) [?:1.8.0_92]
at java.awt.Container.processEvent(Container.java:2236) [?:1.8.0_92]
at java.awt.Component.dispatchEventImpl(Component.java:4889) [?:1.8.0_92]
at java.awt.Container.dispatchEventImpl(Container.java:2294) [?:1.8.0_92]
at java.awt.Component.dispatchEvent(Component.java:4711) [?:1.8.0_92]
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888) [?:1.8.0_92]
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525) [?:1.8.0_92]
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466) [?:1.8.0_92]
at java.awt.Container.dispatchEventImpl(Container.java:2280) [?:1.8.0_92]
at java.awt.Window.dispatchEventImpl(Window.java:2746) [?:1.8.0_92]
at java.awt.Component.dispatchEvent(Component.java:4711) [?:1.8.0_92]
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758) [?:1.8.0_92]
at java.awt.EventQueue.access$500(EventQueue.java:97) [?:1.8.0_92]
at java.awt.EventQueue$3.run(EventQueue.java:709) [?:1.8.0_92]
at java.awt.EventQueue$3.run(EventQueue.java:703) [?:1.8.0_92]
at java.security.AccessController.doPrivileged(Native Method) [?:1.8.0_92]
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76) [?:1.8.0_92]
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) [?:1.8.0_92]
at java.awt.EventQueue$4.run(EventQueue.java:731) [?:1.8.0_92]
at java.awt.EventQueue$4.run(EventQueue.java:729) [?:1.8.0_92]
at java.security.AccessController.doPrivileged(Native Method) [?:1.8.0_92]
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76) [?:1.8.0_92]
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728) [?:1.8.0_92]
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) [?:1.8.0_92]
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) [?:1.8.0_92]
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) [?:1.8.0_92]
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) [?:1.8.0_92]
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) [?:1.8.0_92]
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) [?:1.8.0_92]
原因:看报错日志第一行就能看到,因为判断语句中符号错误导致,因***jexl3***语法中规定,字符串需要用引号包含
//错误语句
${__jexl3("${__P(access_token,)}!=null",)}
//正确语句
${__jexl3("${__P(access_token,)}"!="null",)}
原因:配置的多个host,是相同的变量名,导致无法找到对应的host,则会报错
解决办法:保证host的唯一性,禁用不需要的host
场景:针对一个path(如:***/test/login***),在run之后发现,该取样器跑了两遍,
两次的不同:
排查原因:code302是重定向,需要借助重定向的办法去保证访问成功
状态码302指:请求资源临时移动到其他位置;可能是因为资源所在url发生变化,或者服务器对请求进行负载均衡,将请求转发到其他服务器上。但是客户端应当继续使用原有URL进行后续请求。
重定向原理:
常见问题&解决办法
1、错误重定向目标:即返回的location指向的url是错误的
解决办法:打印日志或使用开发工具查看服务器返回的响应头信息,检查正确
2、循环重定向:服务器返回的Location的URL是原始页面,导致循环
解决办法:限制重定向次数;增加逻辑判断避免循环
3、其他错误:网络连接错误;目标URL无效;权限不足
解决办法:代码中加入异常处理机制
尝试办法一:将取样器接口直接改成重定向之后的接口,再次访问,返回结果中该取样器只跑了一遍
缺陷:由于不确定该地址是否永久有效,会导致
根据网上查找的原因,这种方式并不是错误的,只是一种机制,第一遍是重定向,因为没有携带cookie,所以设置全局变量cookie接即可
排查原因2:不确定是哪个原因
解决办法:把地址修改成可以成功跑通的地址即可
场景:字段a作为参数,从上一个接A返回body中获取,A返回a就作为参数在下一个接口B使用;如果A没有返回,则默认传null;现在因A中没有返回,如何传null
尝试方法一:使用JSON提取器提取a,如果提取不到,则默认值为null
也就是说,在这种情况下,即使有默认值null,也没有实际传null
尝试方法二:将JSON提取器默认改成" ",再run一遍,依然是同样的结果
尝试方法三:将JSON提取器默认值改成NULL ,run一遍,结果相同
尝试方法四:将JSON提取器默认值不填写,run一遍,结果相同
尝试方法五:改成正则表达式提取器,勾选Use empty default value,run一遍,可以成功传null
总结:针对JSON提取器,NULL = null = " "= (什么都不太填写),这几种格式都会让jmeter传空
针对正则表达式提取器,勾选Use empty default value则会传空值。