一、Jmeter总结 1.响应结果乱码问题 (1)方案一 修改如下图:
(2)方案二
2.修改默认语言
3.接口返回数据中文为Unicode(万国码/统一码)转中文
(1)步骤如下 1.添加一个后置处理器(BeanShell PostProcessor) 2.编写转译方法 3.保存,运行
(2)代码如下 String s2=new String(prev.getResponseData(),“UTF-8”); //---------------一下步骤为转码过程--------------- char aChar; int len= s2.length(); StringBuffer outBuffer=new StringBuffer(len); for(int x =0; x <len;){ aChar= s2.charAt(x++); if(aChar==’\’){ aChar= s2.charAt(x++); if(aChar==‘u’){ int value =0; for(int i=0;i<4;i++){ aChar= s2.charAt(x++); switch(aChar){ case’0’: case’1’: case’2’: case’3’: case’4’: case’5’: case’6’: case’7’: case’8’: case’9’: value=(value <<4)+aChar-‘0’; break; case’a’: case’b’: case’c’: case’d’: case’e’: case’f’: value=(value <<4)+10+aChar-‘a’; break; case’A’: case’B’: case’C’: case’D’: case’E’: case’F’: value=(value <<4)+10+aChar-‘A’; break; default: throw new IllegalArgumentException( “Malformed \uxxxx encoding.”);}} outBuffer.append((char) value);}else{ if(aChar==‘t’) aChar=’\t’; else if(aChar==‘r’) aChar=’\r’; else if(aChar==‘n’) aChar=’\n’; else if(aChar==‘f’) aChar=’\f’; outBuffer.append(aChar);}}else outBuffer.append(aChar);} //-----------------以上内容为转码过程--------------------------- //将转成中文的响应结果在查看结果树中显示
prev.setResponseData(outBuffer.toString());
———————————————— 原文链接:https://blog.csdn.net/weixin_42675206/article/details/81064257 4.cookie管理器保存登录后的cookie信息(跳过登录过程,测试后续接口) 把这个表里的所有数据的名称、域名、路径、值都一一写到cookie管理器里,如下图jmeter的这个位置
注意:名称、值、域 必填,路径可不填写 (1)进阶:批量获取cookie信息,跨线程组传递 1.设置配置文件使Cookie管理器保存cookie信息。 修改apache-jmeter-5.2.1/bin/jmeter.properties文件,把CookieManager.save.cookies设置为true,并去掉前面的注释#号,如下图所示:
修改完成后保存,退出,并重启jmeter。 2.在调试取样器和请求中查看具体的cookie信息 在线程组中添加HTTP Cookie 管理器,运行测试计划后,HTTP Cookie 管理器会自动存储这些cookie,变量名称为COOKIE_XXX,XXX对应的是cookie的名称,可以添加【调试取样器】来查看自动存储的cookie值,如下图所示: 下图中有两个cookie值分别为:COOKIE_z92_lastvisit何COOKIE_z92_visitor
这里要注意一下,有时候你会发现这里的cookie不全,所以比较保险的做法下,进入第一个请求中查看request body中的cookie值。如下图所示:下图中有三个cookie值分别为:z92_visitor和z92_lastvisit以及csrf_token三个值。这里比前者多了一个cookie值。
3.设置cookie为全局变量 在BeanShell后置处理程序中使用__setProperty()函数将COOKIE_XXXX设置为全局变量。如下图所示:
4获取并存储Cookie 在HTTP Cookie管理器中通过__P()函数获取全局变量Cookie,并加入到Cookie管理器中。注意名称和在请求中的cookie名称保持一致。如下图的z92_visitor和z92_lastvisit以及csrf_token三个值。
5.jmeter脚本录制 ①创建线程组-创建HTTP代理服务器-修改端口号
②添加排除模式 (懒得手打的跳转 复制粘贴:https://blog.csdn.net/qq_42293487/article/details/83822604)
③查看本机IP(命令框输入:ipconfig)记住ip地址
④配置浏览器代理 在代理框输入第三步记住的ip地址,端口号填写8888,与jmeter修改的端口号保持一致(因为浏览器不同,所以入口不一样,但是设置的步骤是一样的)
第五步。点击启动,启动之后去刚刚的浏览器中操作你要抓包的网站就可以了。(必须要点击启动以后,你的浏览器才能访问网络)
原文链接:https://blog.csdn.net/qq_42293487/article/details/88105978 6.windows下Jmeter压测端口占用问题 百度查找有的是解决方法
https://blog.csdn.net/weixin_43757847/article/details/88188091?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control 7.引用外部文件 (1)引用jar包 一、测试计划中添加目录或jar包到Classpath 操作:测试计划->添加目录或jar包到Classpath–>浏览导入jar包 优点:操作便捷 缺点:1)可移植性差;2)jar包较多时不好管理
二、将需要引用的jar包放在jmeter的extras目录下 操作:将jar包放在jmeter安装目录apache-jmeter-5.0\extras下 优点:比方法1可移植性强一点 缺点:有些jar包放在extras下加载不到,需要放在apache-jmeter-5.0\lib目录下才可以,导致管理比较混乱
三、通过jmeter.properties设置依赖路径 操作:1)jmeter目录下新建一个存放第三方jar包的文件夹third_dependency,将第三方jar包放进去
2)apache-jmeter-5.0\bin目录下找到jmeter.properties设置依赖路径 文件中添加一行:plugin_dependency_paths= …/third_dependency;
优点:可移植性强,jar包管理方便
来自于https://www.cnblogs.com/Clairewang/p/12550965.html
(2)引用java文件 添加Bean Shell组件 在bean shel中通过source(“代码路径”)方法引入java,然后调用方法和java一样,new一个class,再调用里面的add 方法。
代码: //引用外部的Java文件,要用绝对路径 source(“D:\xingneng_work_file\work_file\test_add.java”);
//new生成对象并调用函数 int res = new Myclass().add(1,2);
//生成结果赋值给vars vars.put(“add”,res.toString());
运行结果:
(3)引用class文件 Bean Shell使用代码如下: 用addClassPath(“D:\”)方法引入 class文件,再用import导入包及类,然后就可以像java一样调用了
运行结果: 8.json断言及json提取器的使用 (1)json断言 该组件使您可以执行JSON文档的验证。 首先,它将解析JSON,如果数据不是JSON则失败。 其次,它将使用https://github.com/json-path/JsonPath中的语法搜索指定的路径。如果找不到该路径,它将失败。 第三,如果在文档中找到JSON路径,并要求针对期望值进行验证,它将执行验证。对于null值,在GUI中有一个特殊的复选框。请注意,如果路径将返回数组对象,则将对其进行迭代,并且如果找到期望值,则断言将成功。要验证空数组,请使用[]字符串。另外,如果patch将返回字典对象,则在比较之前将其转换为字符串。
什么是JSON JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式。JSON容易理解,便于阅读和编写;同时计算机也易于解析和生成,所以JSON有广泛的应用。 键值对的形式存在:
(2)JSON断言分析: 返回的数据必须的JSON格式,否则会解析失败。 他将JsonPath语法搜索指定的路径,找不到路径,则会失败。http://goessner.net/articles/JsonPath/ 这个网址去学习JSON语法。 JSON是键值对形式存在,通过路径找到键,可以对该键的值进行校验。 如果键的值为null,GUI中有复选框(Expect null),勾选上则表示以null作为预期值。 如果路径找到的数组对象(在列表页中比较常见这种情况),则会对数组中的数据进行轮询。如果其中有一个值和预期值匹配,那么断言也是成功的。 返回的是字典对象,则需要转为字符串后再进行比较。
(3)JSON断言界面参数说明:
名称:节点的名称,显示在查看结果树中,自己根据实际情况定义。 注释:对该节点进行注释。 断言存在JSON路径:断言JSON元素的路径。 附加断言值:如果要使断言具有某个值,把这个值勾选上。如果写了(3)JSON元素的路径,要把这个值勾选上。 匹配为正则表达式:如果要使用正则表示式,选中该复选框。 预期值:JSON元素路径对应的值。 反转断言:就是否的意思,即如果符合就失败。
(4)json断言详细说明
可以直接在查看结果树中进行JSON语法的测试。测试ok了再直接放在JSON断言中。 $ 表示跟节点。 [] 表示数组,0表示第一个;$[0] 表示跟节点后的第一个对象。 resultcode 即key,这里要获取resultcode的值,所以填写resultcode。
(5)举例: 取第一个id的值,$.data[0].id
(1)json提取器 用法说明 此提取器用于提取请求返回结果中的某个值或者某一组值,用法比正则表达式要简单,标准写法为$.key,其中key为返回结果map中的一个键,如果是多层则继续用.key进行即可,如果遇到key的value值为一个List,则使用.key[n],其中n为list中元素的编号, 原文链接:https://blog.csdn.net/df0128/article/details/86535117
(2)Json提取器语法说明
地址:https://blog.csdn.net/df0128/article/details/86535117 9.文件上传 (1)创建线程组,添加各类组件 这个就不用说了。由于需要登录,所以我加了一个信息头管理器,把token写在里面。
(2)文件上传 有接口文档的话,那就对着文档写,没api文档,就自己抓包看了。(注意:我在线程组下面加了http信息头管理器是因为我下面的“核对数据”和“预览发送”两个步骤需要这个Content-Type,单单的上传文件是不需要这个组件的,加了反而可能会报错)
然后点击高级设置,客户端实现类型选择JAVA
(3)查看结果树 运行一下看一下结果树的反馈(下面两个报错可以忽略,与本主题无关,纯粹是懒所以没改)。
10.文件下载 (1)jmeter文件下载步骤: 首先文件下载接口请求信息填写完全 然后①右键点击线程组->添加->Sampler->Bean Shell Sampler,②或者右键点击线程组->添加->后置处理器>Bean Shell Post Processor。本次以Bean Shell Sampler为例,如下图
输入脚本: import java.io.*; byte[] result = prev.getResponseData(); //这个是获取到请求返回的数据,prev是获取上个请求的返回 String file_name = “e:\BaiDuTuPian.jpg”; //代表存放文件的位置和文件名 File file = new File(file_name); FileOutputStream out = new FileOutputStream(file); out.write(result); out.close(); ———————————————— 原文链接:https://blog.csdn.net/sinat_28317385/article/details/108359217
11.函数的使用 (1)加密函数 ①使用内置函数__MD5进行加密 使用 ${__MD5(w12345678,)} 进行MD5加密(32位小写)
使用KaTeX parse error: Expected group after '_' at position 2: {_?_uppercase(,)} …{__uppercase(${__MD5(w12345678,)},)}
②使用内置函数__digest进行加密 使用${__digest(MD5,w12345678,true,)} 进行MD5加密(默认为小写,第四个参数传true可直接返回大写)
参数说明: Digest algorithm(必填):加密算法,支持:MD2、MD5、SHA-1、SHA-224、SHA-256、SHA-384、SHA-512(其它jmeter自身不支持的加密算法可使用“7.引用外部文件的方式解决”)。 String to be hashed(必填):需要加密的字符串。 Salt to be used for hashing (optional):用于加密的盐。 Upper case result, defaults to false (optional):大写结果,默认为false。 Name of variable in which to store the result (optional):存储结果的变量的名称。
③使用内置方法加密 Jmeter 4.0 以上版本已有自带的MD5加密方法 1)添加 BeanShell Sampler,代码如下: import org.apache.commons.codec.digest.DigestUtils; String str = “w12345678”; String sign = DigestUtils.md5Hex(str); vars.put(“pw”,sign.toUpperCase()); (2)字符串拼接 字符串拼接步骤: 1.打开jmeter上的函数助手,选择—V功能,如下图: 2.把要拼接的值写进去:固定字符串+取出来的参数(这里的空格为固定字符串内的空格,不需要空格的可以去掉) 3.点击生成,就把生成的字符串放到请求头中去就行了,只有这些参数没有其他的话,需要把后面的逗号去掉,这样再运行就可以了
(3)设置全局变量(跨线程组传递变量) ①打开函数助手
输入需要的值然后点击生成按钮,或者直接使用KaTeX parse error: Expected group after '_' at position 2: {_?_setProperty(ne…{userid},)}的格式
②添加BeanShell 取样器或者BeanShell PostProcessor后置处理器,设置局部变量userid和token为全局变量newuserid和newtoken
③调用方式 ${__property(变量名)}
(4)时间戳 在使用jmeter做接口测试的时候,经常会要用到日期这种函数,让系统自动生成一些格式化的数据,方便接口测试,jmeter自身就带有时间戳的函数
1、__time:获取时间戳、格式化时间 (1)、KaTeX parse error: Expected group after '_' at position 2: {_?_time(yyyy-MM-d…{__time(,)}:默认该公式精确到毫秒级别, 13位数 1527822855323 (3)、KaTeX parse error: Expected group after '_' at position 2: {_?_time(/1000,)}:…{__time(yyyy-MM-dd,)}:该公式格式化生成的时间为:2018-10-26 (5)、${__time(yyMMdd,)}:该公式格式化生成的时间为:181026
2、__timeShift(格式,日期,移位,语言环境,变量)函数,可以将时间进行移位,对当前时间增加或者减少对应的时间 (1)、格式 - 将显示创建日期的格式。如果该值未被传递,则以毫秒为单位创建日期。 (2)、日期 - 这是日期值。用于如果要通过添加或减去特定天数,小时或分钟来创建特定日期的情况。如果参数值未通过,则使用当前日期。 (3)、移位 - 表示要从日期参数的值中添加或减去多少天,几小时或几分钟。如果该值未被传递,则不会将任何值减去或添加到日期参数的值中。 “P1DT2H4M5S” 解析为“添加1天2小时4分钟5秒” “P-6H3M”解析为“-6小时+3分钟” “-P6H3M”解析为“-6小时-3分钟” “-P-6H + 3M”解析为“+6小时和-3分钟” (4)、区域设置 - 设置创建日期的显示语言。不是必填项 (5)、变量 - 创建日期的值将被分配给的变量的名称。不是必填项
e.g.:${__timeShift(yy-MM-dd,2018-10-26,P2D,,)}这种返回的时间就是2018-10-28
3、__randomDate(格式,开始时间,结束时间):时间段内随机获取时间 (1)格式默认为yyyy-MM-dd
e.g.😒{__randomDate(yyyy-MM-dd,2018-10-01,2018-10-30)},这种函数就会自动返回20181001-20181030之间的一个日期
(5)jmeter随机取用户自定义变量的值 ${__RandomFromMultipleVars(用户自定义的变量1|用户自定义的变量2)}
用法一:可以在beanshell中将取到的随机值赋给变量s,在引用时直接引用ss即可 s=${__RandomFromMultipleVars(P1|P2,)}; vars.put(“ss”,s.toString());
用法二:在请求体或其他直接为变量赋值的地方,直接使用${__RandomFromMultipleVars(用户自定义的变量1|用户自定义的变量2)} 转载于:https://www.cnblogs.com/applezxy/p/11124184.html
(6)自增函数和计数器 "_counter"函数 功能:这个函数是一个计数器,用于统计函数的使用次数,它从1开始,每调用这个函数一次它就会自动加1,它有两个参数,第一个参数是布尔型的, 只能设置成“TRUE”或者“FALSE”,如果是TRUE,那么每个用户有自己的计数器,可以用于统计每个线程歌执行了多少次。如果是FALSE,那就 使用全局计数器,可以统计出这次测试共运行了多少次。第二个参数是“函数名称” 格式:${__counter(FALSE,test)} 使用:我们将“_counter”函数生成的参数复制到某个参数下面,如果为TRUE格式,则每个线程各自统计,最大数为循环数,如果为FALSE,则所有线程一起统计,最大数为线程数乘以循环数
计数器 Jmeter计数器实现自增功能 如果需要引用的数据量较大,且要求不能重复或者需要自增,那么可以使用计数器来实现 如:新增功能,要求名称不能重复
1.新增计数器 计数器:允许用户创建一个在线程组之内都可以被引用的计数器。 计数器允许用户配置一个起点,一个最大值,增量数,循环到最大值,然后重新开始,继续这样,直到测试结束。
初始值(Starting value):给定计数器的起始值、初始值,第一次迭代时,会把该值赋给计数器 递增(Increment):每次迭代后,给计数器增加的值
最大值(Maximum value):计数器的最大值,如果超过最大值,重新设置为初始值(Starting value),默认的最大值为Long.MAX_VALUE,2^63-1(如果持续压测,建议最好不要设置最大值)
数字格式(Number format):可选格式,比如000,格式化为001,002;默认格式为Long.toString(),但是默认格式下,还是可以当作数字使用
引用名称(Reference Name):用于控制在其它元素中引用该值,形式:${reference_name}
与每用户独立的跟踪计数器(Track Counter Independently for each User):全局的计数器,如果不勾选,即全局的,比如用户#1 获取值为1,用户#2获取值还是为1; 如果勾选,即独立的,则每个用户有自己的值:比如用户#1 获取值为1,用户#2获取值为2。
每次迭代复原计数器(Reset counter on each Thread Group Iteration):可选,仅勾选与每用户独立的跟踪计数器时可用; 如果勾选,则每次线程组迭代,都会重置计数器的值,当线程组是在一个循环控制器内时比较有用。
2.引用计数器
12.控制器 https://www.cnblogs.com/Zfc-Cjk/p/8466136.html 详解 ①循环控制器
②ForEach控制器
这样就再去执行这个控制器就会执行两遍,也可以截取其他集合的变量作为参数来遍历。
③仅一次控制器
④事务控制器
可以理解为一个流程场景,例如发布流程、交易等,需先新建、编辑、提交审核、发布,所有的接口都成功才能发布成功。将流程场景涉及到的所有接口放到一个事务里即可。 特别说明:添加事务后在聚合报告中请求按照事务进行统计,事务中某一个请求报错即整个事务报错。 ⑤IF控制器
判断填写的条件是否成立,成立则执行控制器下的组件 ⑥Switch控制器 (这个理论上是不是也可以里面加其他控制器)
⑦吞吐量控制器
作用:控制其下的子节点的执行次数与负载比例分配,别被名字迷惑了,跟吞吐量没任何关系。也有两种方式: Total Executions:设置运行次数,整个测试计划中总计执行次数 Percent Executions:设置运行比例(1~100之间),整个测试计划中总计执行百分比 Throughtput: 设计的数值 Per User: 依据网上的说明在选择Total Executions时,勾选时会在每个线程中执行的次数。但在3.0版本中尝试使用无效 ⑧随机控制器
⑨随机顺序控制器
其他控制器 先看顶部网址!!! 13.文件大小及文件md5值获取 步骤: ①引用jar包(jar包在该文档同级目录) jar包名称: commons-codec-1.15.jar
②添加前置处理器→BeanShell PreProcessor
③引用
④查看运行结果
14.jmeter调试工具(Debug Sampler)的使用
使用Jmeter开发脚本时,难免需要调试,这时可以使用Jmeter的Debug Sampler,它有三个选项:JMeter properties,JMeter variables,System properties:
1、JMeter properties和System properties:通常都选false,这两个就是JMeter和系统的属性,在Jmeter的bin的jmeter.properties中定义,一般都不会变。 2、JMeter variables:这个是我们自已定义的变量,定义的方式有如下这些: a) 选中测试计划(Test plan),在右边的面板上添加User Defined Variables b) 选中线程组,右键选择 配置元件( config element)–>User Defined Variables c) 通过后置处理器生成的变量 d)使用csv参数化的变量
15.jmeter-CSV参数化 ①创建CSV文件 创建.csv文件,用户名和密码中间以逗号隔开
② 在线程组中添加并配置CSV Data Set Config 1.添加CSV Data Set Config
2.配置CSV Data Set Config(文件地址可以写相对路径,“./为bin目录下”)
?Filename: 指保存信息的文件目录,可以相对或者绝对路径。否则会在jmeter日志文件(jmeter.log目录位置D:\Program Files\apache-jmeter-2.13\bin)中提示:系统找不到指定文件,运行脚本后,登录失败。 ?File encoding: 保持默认。默认为ANSI ?Variable Names: 给csv文件中各列起个名字(有多列时,用英文逗号隔开列名)便于后面引用 ?Delimiter:与 .csv文件的分隔符保持一致。如文件中使用的是逗号分隔,则填写逗号;如使用的是TAB,则填写\t; ?Allow quoted data? :是否允许引用数据,—这个目前还未弄明白,设置成True或者False都能正常引用数据。 ?Recycle on EOF?:到了文件尾是否循环,True—继续从文件第一行开始读取,False—不再循环 ?Stop thread on EOF? :到了文件尾是否停止线程,True—停止,False—不停止,注:当Recycle on EOF设置为True时,此项设置无效。 ?Sharing mode:共享模式,All threads –所有线程,Current thread group—当前线程组,Current thread—当前线程。
All threads:计划中所有线程,假如说有线程1到线程n (n>1),线程1取了一次值后,线程2取值时,取到的是csv文件中的下一行,即与线程1取的不是同一行。 2 Current thread group:当前线程组,假设有线程组A、线程组B,A组内有线程A1到线程An,线程组B内有线程B1到线程Bn。取之情况是:线程A1取到了第1行,线程A2取第2行,现在B1取第1行,线程B2取第2行。 2 Current thread:当前线程。假设测试计划内有线程1到线程n (n>1),则线程1取了第1行,线程2也取第1行。
③引用csv文件中的数据 1.找到需要传递参数的HTTP请求 2.将具体值改为变量引用,引用变量:${变量名}
④读取的csv数据中文乱码问题 将数据存储到txt中,另存为带有bom的utf-8格式,然后修改文件后缀为csv即可
16.jmeter-返回结果生成CSV文档 (1)步骤 ①本次为方便演示故添加csv数据文件设置组件,实际场景应添加JSON提取器,存储提取到的返回数据。
CSV文件使用记事本或Notepad++打开,列之间实际是英文“,”表示,此处需要记住。 CSV参数设置参考“标题15”
②添加http请求,在请求下添加BeanShell PostProcessor
代如下码: FileWriter fstream = new FileWriter("./test01/444.csv",true); //tuer为写入,不填写默认false为清除 BufferedWriter out = new BufferedWriter(fstream);
//String logo = vars.get(“name”); //logo = logo.replaceAll(",",""); 此处注释内容为参数中有多余的“,”时,将逗号转为空字符或其内容,以免文件列错位 //vars.put(“logo”,logo);
out.write(vars.get(“name”)); //写入name的值 注意此处通过get只能调取变量,且直接填写变量名称! out.write(","); //写入英文逗号,csv列之间用逗号分隔 out.write("
s
e
x
"
)
;
/
/
直
接
写
入
字
符
或
变
量
,
此
时
变
量
需
要
{sex}"); //直接写入字符或变量,此时变量需要
sex");//直接写入字符或变量,此时变量需要{}引用 out.write(","); out.write(vars.get(“age”)); out.write(System.getProperty(“line.separator”)); //换行 //out.write("\n"); 写入“\n”也可实现换行
out.close(); fstream.close();
③运行结果
④思考1? 是否可先清除模式打开文件,写入变量的标题,在接口返回时再次用写入模式打开文件录入数据,从而达到每次启动自动清除文件内容的目的。
结果:
思考2? 多个请求的返回参数写入同一个文件
|