文章目录

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());

————————————————
原文链接→

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代理服务器-修改端口号
在这里插入图片描述
在这里插入图片描述

②添加排除模式

      .*\.(js|css|PNG|jpg|ico|png|gif).*

在这里插入图片描述

③查看本机IP(命令框输入:ipconfig)记住ip地址
在这里插入图片描述

④配置浏览器代理
在代理框输入第三步记住的ip地址,端口号填写8888,与jmeter修改的端口号保持一致(因为浏览器不同,所以入口不一样,但是设置的步骤是一样的)
在这里插入图片描述

第五步。点击启动,启动之后去刚刚的浏览器中操作你要抓包的网站就可以了。(必须要点击启动以后,你的浏览器才能访问网络)
在这里插入图片描述
原文链接→

6.windows下Jmeter压测端口占用问题

百度查找解决方法→

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中元素的编号,
在这里插入图片描述

(2)Json提取器语法说明

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
转载地址:https://blog.csdn.net/df0128/article/details/86535117

JMeter正则表达式提取器与JSON提取器(详解)

点击跳转原文地址→

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();

————————————————
原文链接→
在这里插入图片描述

11.函数的使用

(1)加密函数

①使用内置函数__MD5进行加密
使用${__MD5(w12345678,)} 进行MD5加密(32位小写)
在这里插入图片描述

使用${__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)设置全局变量(跨线程组传递变量)

①打开函数助手
在这里插入图片描述

输入需要的值然后点击生成按钮,或者直接使用${__setProperty(newuserid,${userid},)}的格式

②添加BeanShell 取样器或者BeanShell PostProcessor后置处理器,设置局部变量userid和token为全局变量newuserid和newtoken
在这里插入图片描述

③调用方式 ${__property(变量名)} 或 ${__p(变量名)}
在这里插入图片描述
*函数助手里的 p及property的使用

${__P(init,2)} ${__property(init,start,200)}

可以自行定义变量名称,及变量的默认值
P 变量名为init, 值为2 ,使用的时候直接${__P(init,2)}就可以,改变量的结果为2
${__property(init,start,200)} 变量名为init, 默认值为200,同时会将200默认传给start这个变量,start可进行再使用 ${start}

*property函数详解

作用:读取 Jmeter 属性
语法格式:${__property(key,var,default)}
参数讲解:
在这里插入图片描述
小栗子:
${__property(key)}
读取 key 属性
如果找不到 key 属性,则返回 key(属性名)

${__property(key,default)}
读取 key 属性
如果找不到 key 属性,则返回 default

${__property(key,prop,default)}
将读取到的属性值存储到 prop 变量中,可通过 ${prop} 引用
在这里插入图片描述
实际栗子
线程组:
在这里插入图片描述
结果树:
在这里插入图片描述
前三个 sampler 读取的属性是存在的,所以会返回对应的值
最后一个 sampler 读取了不存在的属性,返回了默认值

重点:
如果没有加 , 则代表没有传参数,如: ${__property(keys)}
如果加了 , 代表有传参但没有填值,代表值为 null(空),如: ${__property(keys,)}
对于这个函数,若属性不存在,且默认值传了 null(空),则不会返回属性名,如最后一个 sampler
空不代表默认值可以填 null,这是字符串的 null,不是空

(4)时间戳

在使用jmeter做接口测试的时候,经常会要用到日期这种函数,让系统自动生成一些格式化的数据,方便接口测试,jmeter自身就带有时间戳的函数

1、__time:获取时间戳、格式化时间

(1)、${__time(yyyy-MM-dd HH:mm:ss:SSS,time)} :格式化生成时间格式 2018-10-26 11:08:23:635
(2)、${__time(,)}:默认该公式精确到毫秒级别, 13位数 1527822855323
(3)、${__time(/1000,)}:该公式精确到秒级别, 10位数 1527822871
(4)、${__time(yyyy-MM-dd,)}:该公式格式化生成的时间为:2018-10-26
(5)、${__time(yyMMdd,)}:该公式格式化生成的时间为:181026

${__time(,curTime)}
您可以在以后的请求中使用${curTime}来引用该值。
在这里插入图片描述

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,在引用时直接引用s即可

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.控制器

①循环控制器

在这里插入图片描述

②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取的不是同一行。
² Current thread group:当前线程组,假设有线程组A、线程组B,A组内有线程A1到线程An,线程组B内有线程B1到线程Bn。取之情况是:线程A1取到了第1行,线程A2取第2行,现在B1取第1行,线程B2取第2行。
² Current thread:当前线程。假设测试计划内有线程1到线程n (n>1),则线程1取了第1行,线程2也取第1行。

③引用csv文件中的数据
1.找到需要传递参数的HTTP请求
2.将具体值改为变量引用,引用变量:${变量名}
在这里插入图片描述

④读取的csv数据中文乱码问题
将数据存储到txt中,另存为带有bom的utf-8格式,然后修改文件后缀为csv即可

csv文件不同位置的区别

1.csv文件在线程组外
在这里插入图片描述
同一个线程组内:在同一个线程组内每个线程(即用户)都会调用一次,如果线程设置了循环次数相当于调用次数=线程数x循环次数。(此种情况需要注意,如线程内有多个请求,实际上在同一个线程里的两个请求的只调用了一次,即读取的参数是一样的)
不同线程组内:不同线程之间也相当于是不同的线程(即用户)
2.csv文件在线程组内,请求外
在这里插入图片描述
此种情况设置多个线程也只会调用一次,只有循环时会再次调用。所以执行效果为运行多个线程传参是一样的,只有循环后会再次调用,参数切换到下一行。
3.csv文件在线程组内,请求内
在这里插入图片描述
此种情况与csv文件在线程组外是一样的,每个线程都会调用一次。如果线程设置了循环次数相当于调用次数=线程数x循环次数。(此种情况需要注意,如线程内有多个请求,实际上在同一个线程里的两个请求的只调用了一次,即读取的参数是一样的)

16.jmeter-返回结果生成CSV文档

(1)步骤
①本次为方便演示故添加csv数据文件设置组件,实际场景应添加JSON提取器,存储提取到的返回数据。
在这里插入图片描述

CSV文件使用记事本或Notepad++打开,列之间实际是英文“,”表示,此处需要记住。
CSV参数设置参考“标题15”

②添加http请求,在请求下添加BeanShell PostProcessor
在这里插入图片描述

代如下码(注释的内容建议删掉,可能会报错):

FileWriter fstream = new FileWriter("./test01/444.csv",true);   //true为写入,不填写默认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("${sex}");               //直接写入字符或变量,此时变量需要${}引用
out.write(",");                     
out.write(vars.get("age"));      
out.write(System.getProperty("line.separator"));        //换行
//out.write("\n");                             写入“\n”也可实现换行

out.close();
fstream.close();

③运行结果

在这里插入图片描述

④思考1?
是否可先清除模式打开文件,写入变量的标题,在接口返回时再次用写入模式打开文件录入数据,从而达到每次启动自动清除文件内容的目的。
在这里插入图片描述

结果:
在这里插入图片描述
思考2?
多个请求的返回参数写入同一个文件

17.命令行输入Jmeter提示不是内部或外部命令

命令行输入Jmeter提示不是内部或外部命令,需要在环境变量path中添加jmeter的bin目录绝对路径

1.我的电脑 》 右击 》属性 》 高级系统变量 》 环境变量 》 path 》 后面加上bin目录的绝对路径【如D:\Tools\apache-jmeter-5.0\bin】,保存。再次打开命令行cmd 》 输入Jmeter可以打开Jmeter了。

2.后来网上另一种更好的配置方法,类似于java环境变量的配置。建议下面这种。

新增1个环境变量:
JMETER_HOME=D:\Tools\apache-jmeter-5.0 【jmeter文件夹】

编辑CLASSPATH:
CLASSPATH后面加上 %JMETER_HOME%\lib\ext\ApacheJMeter_core.jar; %JMETER_HOME%\lib\jorphan.jar;

编辑path:
path后面加上 %JMETER_HOME%\bin;

保存。命令行输入jmeter可以启动jmeter说明配置ok。

18.Jmeter 命令行(非GUI模式)执行详解

背景说明:
JMeter执行方式有两种,一种是GUI模式,一种是非GUI模式。
GUI模式就是界面模式,非GUI模式就是命令行模式。GUI模式主要用来编写和调试脚本用的,接口的性能测试最好是采用命令行模式,因为该模式可以和其它框架进行对接,进行自动化测试平台的集成。

非GUI模式适用场景:
1、更省资源,更容易实现多工具集整合;
2、当访问的接口服务需要通过代理服务器才能完成的;
3、当一台机器产生的压力不够时,采用分布式多机远程执行模式,使得一台主控机可以控制多台压力机,同时生成更多的压力请求,达到客户端能模拟大并发请求的目的;
4、可以通过外部传参,让命令行将数据传入到脚本中,使得外部系统调用jmeter时候能更好的进行集成和传参,比如通过jenkins启动和执行接口自动化时,将参数从jenkins的界面传入到jmeter中,就是通过命令行参数进行桥接的。

优点:
1、节约系统资源,无需启动界面
2、便捷快速:仅需启动命令行,输入命令便可执行
3、易于持续集成:可通过shell脚本命令执行

参数详解:
-h 帮助 -> 打印出有用的信息并退出
-n 非 GUI 模式 -> 在非 GUI 模式下运行 JMeter
-t 测试文件 -> 要运行的 JMeter 测试脚本文件
-J 是设置本地jmeter属性,引用变量参数
-G 是设置server的jmeter属性
-l 日志文件 -> 记录结果的文件
-r 远程执行 -> 在Jmter.properties文件中指定的所有远程服务器
-H 代理主机 -> 设置 JMeter 使用的代理主机
-P 代理端口 -> 设置 JMeter 使用的代理主机的端口号

使用方法详解:
前提:为了方便管理,在jmeter的安装目录bin下创建一个文件夹testscript用来存放脚本(.jmx文件),再创建一个文件夹testresult用来存放脚本执行后的结果文件。

一、使用JMeter非GUI模式

1、将要测试的jmeter脚本放到testscript目录下
2、cmd打开命令行模式
3、进入到Jmeter安装目录下的bin目录下
4、执行命令:jmeter -n -t examples\testscript\apd_v3.7_perf.jmx -l examples\testresult\apd3.7-reslut.jtl -j report\01-log.log
可以看到以下信息
在这里插入图片描述
summary+ 是开始这个时点的报告。
summary= 是总结它之前的报告,呈现出的是当前时点之前总的情况,通常是均值。
最后一个summary=是本次压测总的情况,如果脚本按时正常结束的话,最后一次summary里面的值应该和你从GUI打开聚合报告或概括报告的值一致。

在这里插入图片描述

二、无界面分布式压测

当并发量过大单机无法承担需要做分布式压测
执行方法:
1、把脚本和参数文件存放到各台终端相同目录下
2、将每台终端的jmerter-server.bat打开等待主机发号施令
3、在主机命令窗口键入类似以下命令:
jmeter.bat -n -t testscript/Baidu.jmx -R 192.168.182.129:1100,192.168.182.130:1200 -l testresult/01-result.jtl -j report\01-log.log

在这里插入图片描述
命令中-R代表远程 remote ,后面跟随的是每台终端机jmeter-server窗口显示的 ip 和端口,同样,多台终端之间由逗号隔开,其他都与单机命令一样。于是可以看到各台终端机的jmeter-server窗口有关运行和阶段性summary的信息直至运行结束。总体的报告都在你主机保存的那个.jtl文件里。

作者:乘风破浪的姐姐
链接:https://www.jianshu.com/p/ab1c64cd1e98
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

三、生成测试报告

常见命令:

jmeter -n -t 预约.jmx -l result.jtl -e -o abc 

-e -o abc指的是在abc文件夹下生成html报告

运行结果如下:
在这里插入图片描述
进入abc文件夹,就能看到我们生成的html报告了:
在这里插入图片描述

四、报告样式优化

19.字符串截取

方法一

直接引用

 ${__javaScript("${__time(,)}".substring(4\,14),)}      //截取时间戳

方法二

添加BeanShell处理器

   String content = "123456";   //定义字符串
   content.substring(0,3);    //截取下标0到2,3不截取

20.分布式

1.具体步骤:

1.修改 master 配置
修改jmeter.properties remote_hosts字段值,IP 为分布式 agent 的 IP 和端口。端口默认值 1099。
remote_hosts=agent1IP:1099,agent2IP:1099
在这里插入图片描述
在这里插入图片描述

2.修改 slave 配置
修改 jmeter.properties remote_hosts 字段值,IP 为本机的 IP 和端口。端口默认值 1099。
remote_hosts=本机IP:1099
修改server.rmi.ssl.disable=true

3.启动slave机服务
windows中双击jmeter-bin目录下jmeter-server.bat文件
在这里插入图片描述
4.启动master 机,通过运行-远程启动/远程启动所有 运行slave机
在这里插入图片描述
5.jmeter分布式测试中master机的测试结果响应数据为空。
原因是:
分布式测试中,通过远程启动代理服务器,注重的而是高并发,默认查看结果树中的响应数据为空,只有错误信息会被报回。
如果想要结果返回,直接把master机 bin\jmeter.properties文件中的 mode=Standard 之前的 # 号去掉,重启jmeter即可。

2.修改默认端口号:

1.修改 slave 配置
修改 jmeter.properties 配置文件 server_port=8889
修改server.rmi.localport=8889
1.修改 master 配置
修改 jmeter.properties remote_hosts字段值,IP 为分布式 agent 的 IP 和端口。端口为8889。
remote_hosts=agent1IP:8889,agent2IP:8889

3.压测命令(linux):

1.分别在不同 slave 上启动分布式 agent
jmeter-server -Jserver.rmi.ssl.disable=true -Djava.awt.headless=true -Djava.rmi.server.hostname=agent1IP

jmeter-server -Jserver.rmi.ssl.disable=true -Djava.awt.headless=true -Djava.rmi.server.hostname=agent2IP
2.master 机器上使用命令
jmeter -Djava.awt.headless=true -Jserver.rmi.ssl.disable=true -n -t c.jmx -R agent1IP,agent2IP -l test.jtl

4.常见问题排查

1.首先要保持jmeter和java的版本一致
2.启动slave机服务,首先要保证master机器和slave机器网络是通的,需要在master执行telnet 192.168.4.187 8889 ,ip为slave机器ip,端口为slave端设置的端口,如果能正常进入到命令界面,证明和slave端连接是通的
在这里插入图片描述
在这里插入图片描述
3.执行性能压测,master日志没有返回任何执行结果,slave有执行日志
如下图slave机显示接收到了脚本但未执行完成
在这里插入图片描述
打开slave机 jmeter-server.log日志文件,查看报错信息如下
由日志可以看到提示连接2.0.1.85异常,查看master机ip,发现该ip是一块虚拟网卡,只需要禁用该网络连接即可
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
再次运行执行成功
在这里插入图片描述
4.同第三个问题,如果需要连接vpn才能访问,虚拟网卡无法禁用。如何让slave机器知道把运行结果返回给master的哪个ip?
答:在master机bin目录下system.properties文件中最后加入java.rmi.server.hostname=master的ip,再次运行成功。
在这里插入图片描述

在这里插入图片描述

5.另外一个问题执行机日志如下
在这里插入图片描述
下图可以看到脚本中有配置参数化-csv数据文件,但是slave机对应目录下并未配置id.csv文件,配置后再次运行,执行成功
在这里插入图片描述
6.在slave上(linux系统)运行jmeter-server时,出现“An error occurred: Cannot start. localhost is a loopback address”错误

解决方案:
方法一:运行以下命令:./jmeter-server -Djava.rmi.server.hostname=192.16…(本机ip)

方法二:修改jmeter-server文件

vi jmeter-server 将jmeter-server中的RMI_HOST_DEF=-Djava.rmi.server.hostname=192.16…(本机ip)

运行./jmeter-server即可

备注:Linux下后台执行,启用server:nohup ./jmeter-server -Djava.rmi.server.hostname=192.16… &

查看确定jmeter是否启动成功:ps axu | grep jmeter

5.jmeter搭建分布式性能监听(Windows为主机,Linux为从机)

一、注意事项:
1、主机和从机的jmeter版本一致;
2、主机和从机的jdk版本一致;
3、主机和从机的jmeter的jar包要一致

二、文件配置
主机上修改jmeter配置文件
1、进入jmeter的bin目录下找到jmeter.properties文件,配置从机地址
在这里插入图片描述

找到remote_hosts,加上从机IP及端口
在这里插入图片描述

2、进入jmeter的bin目录下找到jmeter.bat文件,配置主机地址
在这里插入图片描述

找到set rmi_host,配置主机地址
在这里插入图片描述

从机上修改配置
1、将jmeter包上传到从机上,【vim /etc/profile】配置jmeter环境变量

export JMETER=/home/wyp/apache-jmeter-3.2
export JMETER_PATH=${JMETER}/bin
export PATH=$PATH::${JMETER_PATH}

在这里插入图片描述

2、安装jdk,【vim /etc/profile】配置jdk环境变量

export JAVA_HOME=/home/wyp/jdk1.8.0_281  #jdk安装目录
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
export PATH=$PATH:${JAVA_PATH}

在这里插入图片描述
3、执行 source /etc/profile 使环境变量生效

4、检查jmeter和jdk是否配置好

执行 jmeter -v 检查jmeter是否配置好
在这里插入图片描述
执行 java -version 检查jdk环境是否配置好
在这里插入图片描述
5、找到jmeter的bin目录下的jmeter.properties文件,配置从机地址

remote_hosts=127.0.0.1,192.168.25.51【从机地址】
server_port=1098【从机端口】
server.rmi.ssl.disable=true
server.rmi.port=1098
server.rmi.localport=1098

在这里插入图片描述
6、找到jmeter的bin目录下的jmeter-server配置从机ip

RMI_HOST_DEF=-Djava.rmi.server.hostname=192.168.25.51

在这里插入图片描述

三、脚本启动
1、在jmeter的bin下执行 ./jmeter-server -Djava.rmi.server.hostname=192.168.25.51,启动从机。

如果遇到提示“./jmeter-server: Permission denied”,执行 chmod 777 jmeter-server 赋权
在这里插入图片描述
2、主机启动
在这里插入图片描述

————————————————
版权声明:本文为CSDN博主「小五da老虎」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_37499398/article/details/118810237

21、linux 非GUI运行Jmeter

1、linux下修改jmeter启动参数,Jmeter命令行参数

一、在linux中,使用非gui的方式执行jmeter。若需更改参数,必须先编辑jmx文件,找到对应的变量进行修改,比较麻烦。因此,可以参数化一些常用的变量,直接在Jmeter命令行进行设置

二、参数 -J 和 -G

1、格式:-J变量名=值 -G变量名=值

2、相同之处:设置jmeter属性,例如线程数、循环次数、ramp up-time等

3、不同之处:-J是设置本地jmeter属性;-G是设置server的jmeter属性(只有设置了远程机,开启了远程服务,才需要用到-G)

三、以设置本地jmeter属性为例,先在windows下编辑脚本,将线程数、循环次数、ramp up-time等参数化

1、添加用户自定义变量(添加变量的具体方法请参考Jmeter添加变量的四种方法)

定义三个变量和变量对应的默认值,例如${__P(threadNum,1)},表示变量threadNum的默认值为1

在这里插入图片描述
2、引用用户自定义变量,将线程属性和用户自定义变量关联起来
在这里插入图片描述
3、运行脚本,验证变量是否设置成功

两个样本请求的线程数都为1,说明设置成功(自定义变量中,变量的默认值都为1)

在这里插入图片描述
四、保存脚本,上传到linux中

1)执行命令:jmeter -n -t httptest.jmx -l log_httptest.jtl -JthreadNum=100 -JloopNum=10 -JrampupTime=10

其中-JloopNum为-1时,代表永远执行。
在这里插入图片描述
2)将log_httptest.jtl文件传到windows下,查看结果
在这里插入图片描述
3)再次运行脚本时,无需编辑脚本,只需要在执行命令中更改threadNum、loopNum和rampupTime的值,即可修改线程属性

例子:RGS="-Xms512m -Xmx3072m" ../jmeter.sh -n -t XXXX.jmx -JthreadNum=20 -JrampupNum=5 -JloopNum=-1 -Jduration=300 -JstartupDelay=1 -l result_20_repli12.jtl

RGS=“-Xms512m -Xmx3072m”:设置jemter运行内存,最大为3072m,最小为512m
…/jmeter.sh -n -t XXXXX.jmx:通过命令行模式执行XXXXX.jmx脚本,-n是通过命令行的意思,-t是指定的脚本
-JthreadNum=20:设置并发用户数为20
-JrampupNum=5:设置5秒内启动20个并发用户
-JloopNum=-1:永远循环
-Jduration=300:持续运行300s
-JstartupDelay=1:延迟1s后启动
-l result_20_repli12.jtl:指定生成result_20_repli12.jtl文件,-l是指定生成测试结果的保存文件(.jtl格式)

五、非GUI运行Jmeter,jtl文件没有请求和响应数据的解决办法

Jmeter官方一直强调要在非GUI模式下运行Jmeter:Run your JMeter test in command-line non-GUI mode。

但在非GUI模式下运行生成的jtl文件是不会记录请求数据和响应数据的,如果在脚本中设置了断言,断言也会失败,
解决办法

Jmeter为了减少压力机负担,默认这些信息不保存,如果想保存这些信息,可以做出如下配置:

1、修改bin目录下的user.properties文件,追加配置:

jmeter.save.saveservice.output_format=xml
jmeter.save.saveservice.response_data=true
jmeter.save.saveservice.samplerData=true
jmeter.save.saveservice.requestHeaders=true
jmeter.save.saveservice.url=true
jmeter.save.saveservice.responseHeaders=true

2、修改bin 目录下的jmeter.properties

jmeter.save.saveservice.response_data=true

jmeter.save.saveservice.samplerData=true

建议
建议在调试或者基准测试时使用以上配置信息,但是真正的压测过程中,注释掉上述新增的内容。
因为 JMeter 在压测工程中,如果开启配置参数,它会边压测,边将请求和响应数据写入 jtl 文件,无形之中加重了 JMeter 的负担,影响压力源的性能,进而影响测试结果。

1、jmeter参数化文件路径问题

win下做好的带参数化文件的脚本,要放到linux上面运行,如果在windows上就把参数化文件路径改为了linux上参数化文件的路径,比如改为/root/data/id.txt,保存后,会变成\root\data\id.txt,这样,传到linux上后,由于参数化文件路径不正确,会导致脚本运行失败,如果解决这个问题呢?

方案一:linux服务器上修改路径
脚本上传到linux服务器后,再vim修改脚本中参数化文件的路径

方案二:参数化路径
比如,参数化文件我放到jmeter的bin目录下,参数化文件名为data.txt
如果在win上,路径为:D:\apache-jmeter-5.1.1\bin\data.txt
如果在linux上,路径为:/usr/local/apache-jmeter-5.1.1/bin/data.txt

先自定义变量,存储win和linux上的参数化文件路径
在这里插入图片描述

csv设置
在这里插入图片描述

方案三:自动获取路径(推荐)
原文链接

2、如何生成有时间作为名称的测试结果jtl文件

直接在【聚合报告】的日志写入文件栏位按照Linux下路径习惯写好,

如:/home/bjqa/apache-jmeter-3.0/logs/morePresult${__time(YMD)}${__time(HMS)}.jtl
则测试结果会在 /home/bjqa/apache-jmeter-3.0/logs/目录下生成类似 morePresult201608151722.jtl

特别的,这里不要写相对路径,相对路径不是很靠谱,绝对路径可以绝对的找到日志文件。此时Jmeter运行命令如下:jmeter -n -t /home/bjqa/apache-jmeter-3.0/testplans/realnameauthINFTest/RNA_INFtest.jmx

看到没有,根本不需要增加 参数 【-l xx.jtl】来生成日志文件,因为测试计划的jmx 【聚合报告】里面已经指定过了,去/home/bjqa/apache-jmeter-3.0/logs这里就能查到日志。

3、Linux环境下安装和运行jmeter

①安装jmeter
使用rz命令将安装包上传至对应的文件路径

rz

通过对应命令将zip/tar.gz压缩文件解压

②配置jmeter环境变量
使用vim命令编辑/etc/profile文件

vim /etc/profile

替换/mytest/jmeter/路径改为实际jmeter安装路径,光标移动至文档最后,插入要添加的内容,

export JMETER_HOME=/mytest/jmeter/
export PATH=$JMETER_HOME/bin:$PATH
export CLASSPATH=$JMETER_HOME/lib/ext/ApacheJmeter_core.jar:$JMETER_HOME/lib/jorphan.jar:$CLASSPATH

编辑成功后,使用Esc键退出编辑模式,:wq保存当前结果

source /etc/profile

注:
/mytest/jmeter/是jmeter的安装路径
配置PATH路径的目的:不用必须在jmeter根目录下才能执行jmeter命令,可以在任何目录下执行

注:权限问题
如果执行jmeter命令,提示

../bin/jmeter: Permission denied

解决方法:给Jmeter安装目录授权,切换至jmeter安装目录,执行以下命令

chmod -R 777 apache-jmeter-5.4.1

③调试并上传脚本
在本地电脑将脚本调试成功后,将csv参数化文件、jmx文件、引用的外部java文件等上传至Linux服务器
注:所有文件路径需要填写Linux中对应的文件路径
在这里插入图片描述
④开始测试
命令1
在当前脚本所在路径下执行以下命令

jmeter -n -t test.jmx -l /mytest/testscript/result/test.jtl -e -o /mytest/testscript/report

参数说明
test.jmx:压测脚本
/mytest/testscript/result/test.jtl:运行结果存放路径
/mytest/testscript/report:图形报告存放路径
-n:以NoGUI方式运行脚本
-t:后面接脚本名称
-l:后面接日志名称,保存运行结果
-e:运行结束生成测试报告
-o:测试报告目录路径

4、使用Jmeter输出错误响应结果到日志

通过用BeanShell PostProcessor简单处理断言是否成功,如果失败打印 结果到日志到指定的目录文件夹中,方便查阅。
①断言语句为包含匹配模式,如下:
在这里插入图片描述

String response="";
String Str="悦读汇1";//需要断言包含的内容
response=prev.getResponseDataAsString();//获取当前的请求结果
if(response==""){
	Failure=true;
	FailureMessage="系统无响应";
     log.error(FailureMessage);
	}
else if(response.contains(Str)==false){
	Failure=true;
	String MSG="\n部分断言不通过,请排查是性能问题还是程序代码问题:";
	FailureMessage=MSG+"\n"+"期望包含内容:"+Str+"\r\n"+"\n响应内容:\n"+response+"\n";
	log.error(FailureMessage);
	}

②断言需要实现完全匹配,则代码如下:
在这里插入图片描述
在这里插入图片描述

String response="";
String Str="{\"code\":200,\"success\":true,\"data\":null,\"message\":\"登录成功\",\"traceId\":\"EA902A080CFB49418A16CD1EE8E0C7CC\",\"total\":0}";//需要断言匹配的内容,注意双引号前需要加反斜杠
response=prev.getResponseDataAsString();//获取当前的请求结果
if(response==""){
	Failure=true;
	FailureMessage="系统无响应";
     log.error(FailureMessage);
	}
else if(response.equals(Str)==false){
	Failure=true;
	String MSG="\n系统返回响应结果与期望结果不一致!,请排查是性能问题还是程序代码问题:";
	FailureMessage=MSG+"\n"+"期望结果:"+Str+"\r\n"+"\n响应内容:\n"+response+"\n";
	log.error(FailureMessage);
	}

③执行语句如下
jmeter -n -t err.jmx -l err.jtl -j log.log
在这里插入图片描述
在这里插入图片描述

22、通过beanshell提取json中的数据

通过beanshell提取json中的数据
beanshell中主要用到与json相关的class时JSONObject和JSONArray,这两个class都在jar中

若要在beanshell中使用json.jar,下列条件任意一个满足都是可行的
1、java的lib中包含有json.jar;
2、jmeter的lib中含有json.jar;
3、jmeter的Test Plan底部,可以添加json.jar到classpath;

Beanshell处理json

import org.json.JSONObject;

JSONObject json = new JSONObject(new String(data));
vars.putObject("json_name", json.getString("name"));

Beanshell处理jsonArray

import org.json.JSONArray;
import org.json.JSONObject;

JSONArray jsonarray = new JSONArray(new String(data));
JSONObject json = jsonarray.getJSONObject(1);  //从jsonaray中取出json,数字是数组序号
vars.putObject("jsonarray_name", json.getString("name"));

23、JMeter日志查看与日志分析

1、JMeter日志概览

jmeter日志文件保存在bin目录中,名称为jmeter.log。我们可以在面板中直接察看日志,点击右上角黄色标志物可以打开日志面板,再次点击收起
在这里插入图片描述

2、JMeter自定义日志

前面所看到的都是系统日志,也就是JMeter本身所打印的日志。如果我们自己想输出一些日志,该怎么办呢?这个一般就要借助Beanshell了。
在这里插入图片描述
在实际项目中,将JMeter脚本部署到Linux服务器上进行压力测试,存在一些日志详情查看的不便之处:

吞吐量统计中包括了所有请求,包括一些辅助请求(beanshell请求),导致真正的tps统计数据不准确。
业务是否成功,以及具体失败原因难以排查。
这就需要用到beanshell下的自定义日志。log.info,log.error,如用log.error()打印错误信息

import org.apache.log4j.Logger;

// 获取接口的响应数据
String result = prev.getResponseDataAsString();

if(result.contains("error")){
    Failure=true;
    log.error("接口失败: " + result);
}

当然,自定义日志最重要应用场景还是在Linux服务器上压测时,方便查看日志信息(因linux上无图形化界面)

比如,获取orderid时脚本

import org.apache.log4j.Logger;

// 获取接口的响应数据
String result = prev.getResponseDataAsString();
// 从JSON提取器中获取code和orderId
String code = vars.get("code");
String orderId = vars.get("orderId");

if(code.equals("0")){
	log.info("place order success, orderId=" + orderId);
}else{
	Failure=true;
	log.error("FailureMessage: " + result);
}

将该脚本上传到Linux中,顺便写个启动脚本:startup.sh

#!/bin/bash
jmeter_log=/home/xxx/jmeter.log

if [ -f "$jmeter_log" ]; then
 // 将原日志文件备份后删除
 cp $jmeter_log /home/xxx/jmeter.log_back
 rm -rf $jmeter_log
fi
// 启动JMeter脚本
jmeter -n -t /home/xxx/test.jmx -l /home/xxx/result/test.jtl -j ../result/log/jmeter_error.log

命令解释:使用该命令调用jmeter进行性能测试,-n:命令模式运行,-t : 后面跟的是需要执行的脚本名称,-l :后跟的是聚合报告保存路径,-j :跟的是日志保存路径,

运行脚本后,cat jmeter_error.log即可查看日志详情

3、JMeter日志分析

针对该日志写一个日志分析脚本logAnalysis.sh:

#!/bin/bash
jmeter_log=/home/test/jmeter.log
thread_num=`grep 'Thread started' $jmeter_log|tail -n 1|awk -F"-" '{print$6}'`
start_time=`grep 'All thread groups have been started' $jmeter_log|awk -F" " '{print $1,$2}'|awk -F"," '{print $1}'`
end_time=`grep 'Shutdown hook ended' $jmeter_log|awk -F" " '{print $1,$2}'|awk -F"," '{print $1}'`

final_success_time=`grep "place order success" $jmeter_log|tail -n 1|awk -F" " '{print$1,$2}'|awk -F"," '{print$1}'`
success_running_time=$[ $(date -d "$final_success_time" +%s) - $(date -d "$start_time" +%s) ]
running_time=$[ $(date -d "$end_time" +%s) - $(date -d "$start_time" +%s) ]
cancle_times=`grep "cancle orders success" $jmeter_log|wc -l`   //撤单次数

success_times=`grep success $jmeter_log|wc -l`   // 成功次数
failure_times=`grep FailureMessage $jmeter_log|wc -l`
request_times=$[ $success_times+$failure_times ]
error_rate=`echo "scale=2; $failure_times/$request_times*100" | bc`
qps=$[ $request_times/$running_time ]
throughput=$[ $success_times/$success_running_time ]

echo -e '线程数:'$thread_num
echo -e '请求次数:' $request_times
echo -e '成功次数:' $success_times
echo -e '失败次数:' $failure_times
echo -e '撤单次数:'$cancle_times
echo -e '错误率:' $error_rate'%'
echo -e '开始时间:'$start_time
echo -e '结束时间:'$end_time
echo -e '最后成功请求时间:'$final_success_time
echo -e '请求时间:' $running_time 
echo -e '成功运行时间:'$success_running_time
echo -e '吞吐量:'$throughput'/s'
echo -e 'QPS:'$qps'/s'

当JMeter脚本运行一段时间后,执行logAnalysis.sh,效果如下:

线程数:200
请求次数: 120000
成功次数:120000
失败次数: 0
错误率: 0%

吞吐量:9000/s
QPS:9000/s

可以看到,输出信息全面清晰。这样,我们就可以在linux下运行JMeter压测脚本时,实时获取压测详情了。
原文链接

24、BeanShell

1.拼接、插入数据

在这里插入图片描述

String serverName="morphology";   //创建字符串
String text=vars.get("text");    //获取jmeter的变量text,text可以从CSV数据文件中读取,也可以从用户自定义的变量中读取。
String timestamp1="${__time(,)}";  //也可以引用jmeter函数
String num=vars.get("num");
String id= timestamp1 + num;   //拼接字符串timestamp1和num 生成新的字符串id

String data1="{\"callback\":\"\",\"content\":{\"text\":\""+text+"\"},\"id\":\""+id+"\",\"resourceUrl\":\"\",\"serverName\":\""+serverName+"\"}";   //将字符串text、id、serverName插入到字符串data1中,此处字符串data1中json格式数据的引号需要在前面加\转义,"+变量名+"可插入指定字符串

vars.put("data1", data1);     //将字符串data1输出,输出后可通过jmeter ${data1}进行引用

请求数据如下
在这里插入图片描述
在这里插入图片描述

2.json数据构建及转字符串

需要先导入json-2014107.jar包,将jar包放入/appche-jmeter-5.0/lib目录下
在这里插入图片描述

json包下载地址:https://mvnrepository.com/ (国内的maven地址)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

构建json数据
在这里插入图片描述

import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.json.JSONArray;

// 先设置1个JSONObject、一个JSONArray  
JSONObject jsono = new JSONObject();
JSONArray  jsona = new JSONArray();

//JSONArray传值
jsona.put("tom");
jsona.put("kate");//["tom","kate"]

//JSONObject传值
jsono.put("name",jsona);//{"name":["tom","kate"]}

String data3=jsono.toString();   //将json数据转为字符串类型
log.info(data3);     //将字符串data3打印到日志

在这里插入图片描述

import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.json.JSONArray;

JSONObject jsono1 = new JSONObject();
jsono1.put("name","name"); //{"name":"name"}

JSONObject jsono2 = new JSONObject();
jsono2.put("id","id");    //{"id":"id"}

// 先设置一个JSONArray  
JSONArray  jsona = new JSONArray();

//JSONArray传值
jsona.put(jsono1);//[{"name":"name"}]
jsona.put(jsono2);//[{"name":"name"},{"id":"id"}]

//设置1个JSONObject  
JSONObject jsono = new JSONObject();

//JSONObject传值
jsono.put("name",jsona);//{"name":[{"name":"name"},{"id":"id"}]}

String data3=jsono.toString();   //将json数据转为字符串类型
log.info(data3);

3.解析返回的json数据

首先需要将json的jar包导入jmeter文件中;jar包放入 \lib\ext 中;
jar包地址: 链接:https://pan.baidu.com/s/16IfQxhDaCLdXzYljuAM05w
提取码:8888
包放入jmeter中后,需要在beanshell处理器中导入

import org.json.JSONObject;
import org.json.JSONArray;
//或者 import org.json.*;

//此json包提供了俩个方法可以对json数据进行处理(getJSONObject,getJSONArray),一个是操作json对象,一个是操作jaon数组
JSONObject responseJson = new JSONObject(response);
JSONArray  data = responseJson.getJSONObject("data").getJSONArray("dataList");
JSONObject data_1 = (JSONObject)data.get(0);

4.BeanShell中报错:org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval

在这里插入图片描述
Map方法中不能指定数据类型,List中同理
在这里插入图片描述
修改后就执行成功了。

5、Jmeter Beanshell脚本报错看不懂如何解决

我们经常使用Beanshell进行数据处理,使用过程中可能会用到自己编写的一些jar包,运行脚本后会报出一些看不懂的错误。
例如:

Error invoking bsh method: eval	Sourced file: inline evaluation of: ``import com.aaa.xls.*; import jxl.read.biff.BiffException; import jxl.write.Write . . . '' : Typed variable declaration : Object constructor

像这种类型的报错,很难定位到原因。

建议:使用JSR223 PreProcessor进行Beanshell脚本的调试(好处:JSR223 PreProcessor会显示更为具体的错误,如下)

Target exception: java.lang.NoClassDefFoundError: org/apache/commons/

使用方法:选择Language设置为:java;将Beanshell里的所有代码放在JSR223 PreProcessor里运行。
在这里插入图片描述
在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐