Jmeter

231 阅读9分钟

1、安装

1.1、下载软件

进入JMeter下载地址页面,如下图,有两个版本可供下载:

  • Binaries:二进制版,即已经编译好、可直接执行。
  • Source:源代码版,需要自己编译。

图片.png

MAC系统下载apache-jmeter-5.4.3.tgz(windows系统下载apache-jmeter-5.4.3.zip),下载完成后,解压,可以通过Finder(访达)页面双击这个文件解压,也可以通过终端输入tar -zxvf apache-jmeter-5.4.3.tgz解压。

1.2、启动软件

1.进入目录下启动

cd */apache-jmeter-5.5/bin
sh jmeter

2.通过环境变量启动

设置环境变量路径:

第一步:vi ~/.bash_profile

第二步:添加如下内容:
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home
export JMETER_HOME=/Users/edy/Downloads/apache-jmeter-5.5/
# 冒号前代表JDK目录下的bin目录,冒号后代表当前目录
export PATH=$JAVA_HOME/bin:$PATH:.:$JMETER_HOME/bin:$PATH

第三步:执行命令:
source ~/.bash_profile

最后,直接在终端输入jmeter,启动jmeter成功

1.3、修改Jmeter语言

两种方法:

  1. 进入jmeter界面,点击【options】-【choose language】-【chinese(simplified)】
  2. 在jmeter安装路径bin目录下:搜索jmeter.properties,打开该文件,搜索#language=en,将#language=en修改为language=zh_CN。

2、简单使用

2.1、准备一个 HTTP 接口

这里创建一个springboot项目,同时写一个简单的接口:/run,直接返回一个JSON串:

 {
    code = 0,
    msg = "ok"
}

项目对外暴露出 8532 端口。

2.2、添加线程组

在测试计划添加一个线程组 (Thread Group)

图片.png

添加完成之后可以看到下面的内容

图片.png

在线程组中,最为主要的就是 Thread Properties 的配置了,不过这里先不对这个进行修改,先保持默认值。

因为首先要做的事情是,把测试接口调试通!如果接口没调好,设置再多的线程也没有意义!

所以这里只把名字改成了 sample1 。

线程组有了,就相当于有了一个骨架,下面就要对这个线程组填充内容,让它丰富起来。

由于我们主要是对 HTTP 接口进行测试,所以大部分内容会是和 HTTP 相关的。

2.3、添加 HTTP 请求默认值

在线程组里面,添加一个 HTTP 请求默认值的配置元件 (HTTP Request Defaults)

图片.png

这里一般会配置一些不怎么变的东西,正常就是接口的域名信息,指定好之后,后面就可以不用在填接口的域名了。

下面就把测试接口的 IP 和 端口填上去。

图片.png

2.4、添加 HTTP 信息头管理器

请求头,大部分接口都会有要求的,最常见的应该就是 Content-Type 。

这里就可以添加一个 HTTP 信息头管理器(HTTP Header Manager)来管理这些请求头。

图片.png

测试接口是 JSON 格式的,所以要把 Content-Type 和 application/json 配置上去。

图片.png

再下一步就是真正的请求了。

2.5、添加 HTTP 请求

在线程组里面添加一个 HTTP Request 类型的 Sampler。

这一个步骤要根据对应的测试接口填写对应的信息。

以测试接口为例:

  1. Web Server 这一块内容不用填,我们在 HTTP 请求默认值 里面已经配置了。
  2. 测试接口是 GET 请求, 测试接口的相对路径是 /run
  3. 接口参数填了 a=b&c=d ,因为是 GET 请求,放到相对路径上面去也是可以的。

到这里的话,对这个接口的请求内容已经准备好了。

要怎么判断请求这个接口是不是成功了呢?

接口成功与否,一般会有几类标识,一类是当状态码为 2xx 时就当作是成功的,一类是返回的 JSON 里面包含了一个 code ,用这个 code 的值来判断。

上面的测试接口是属于第二类,所以要判断的是返回内容里面 code 的具体值是什么。

回想到单元测试,会有一个断言的步骤去判断是不是达到了预期的结果。

同样的,Jmeter 这里也有这个内容。这里选用的是 JSON 断言。

2.6、添加 JSON 断言

在线程组里面添加一个 JSON 断言(JSON Assertion)

示例接口返回 code 为 0 时,才是成功的,所以可以这样填写

首先是判断节点存在与否,其次是勾选断言值,填上期望值。

现在请求有了,断言有了,要怎么查看结果呢?

这里就要请出监听器这个神奇的东西了。

2.7、添加监听器

监听器的种类有很多,这里选择查看结果树(View Results Tree)和聚合报告(Aggregate Report)两个。

这个时候,整一个测试计划是这样的:

运行一下,打开查看结果树,可以看到测试接口已经跑成功了,返回的 code 确实也是 0。

如果把 JSON 断言里面的 code 调整成 1,查看结果树这里就会有错误提示:

再来看看聚合报告长什么样:

主要就是平均响应时间,中位数,错误率,吞吐量这些常见指标。

到这里是不是就结束了呢?

当然没有结束,从刚才的结果来看,明显才请求了一次接口,请求一次接口怎么测试接口的压力呢?

其实一直到看到结果是能成功请求接口,返回正常的数据了,才算是刚刚把接口那部分配置调试好,并没有真正的给压力到测试接口。

前面在创建线程组的时候,采取的都是默认值 1,下面可以调整线程组的一些配置来达到压测的目的。

好比说把线程数调成 100,循环 100 次。

3、参数化

3.1、准备数据

场景有了,接口也有了,再下一步就是准备要用的数据了。

这里是用 CSV 文件来做为数据源,所以我们把接口要用到的参数放进去。

准备了20条数据,第一列是用户名,第二列是密码,第三列是appkey,第四列是结果,表明用前面三列数据去调用登录接口,应该成功还是失败。

然后在线程组里面添加一个 CSV 的配置原件。

在里面最主要的配置是 文件路径变量名

文件路径没什么好说的,就是 csv 文件所在的具体路径。

可以看到上面的 csv 文件,我们是没有定义头部的,放的直接是数据,所以每一列数据代表什么需要有一个标识。

这里的变量名可以认为就是给准备的每一列数据起个别名,便于后面的使用,示例这里是有4个的,每一个都是用英文逗号隔开。

3.2、配置HTTP请求

其中 name, pwd 和 appKey 这三个变量是前面已经定义好了的,所以这里可以直接用  ${xx}  的方式去使用。

sign 这个参数是没有定义的,所以要加一个 BeanShell PreProcessor 来处理一下。

到这里,请求已经配置好了,下面就是要判断登录是不是成功的了。

3.3、断言

断言这里是要判断返回的 JSON 结构里面的 code 值是不是和 csv 文件里面定义的一样。

所以这里选择的还是 JSON Assertion 。

要把期望值调整成变量名,这样它才会根据不同的入参判断不同的结果,上图的例子是  ${login_res}

添加结果树,调整线程组的循环次数为20,再运行这个线程组,就可以看到对应的结果了。

可以看到的是,20条数据都跑了一次,所有的用例都是可以过的。

但是这里有一个问题,密码是明文传输的!!!

这个是大忌,绝对不允许的,正常都会加密或哈希之后再传输。所以这里要做一个优化。

也就引入了,自定义 jar 包的使用。

3.4、自定义jar包调整

首先我们需要写一些 JAVA 代码来编译成一个 jar 包。

这里我是直接写好了,直接用就可以了。

调整一下 BeanShell PreProcessor ,如下图所示:

首先是先引入自定义 jar 包,其次是从 vars 里面拿到明文密码,然后是调用 jar 包里面的 getPwd 的方法对密码进行处理,最后再把处理好之后的密码放到一个新变量 ePwd 里面。

由于之前的 sign 参数是写死的123,这里也改成调用 jar 包里面的 getSign 方法来生成。

由于密码参数换了一个变量,所以要调整一下 HTTP 请求。

最后再次运行,可以看到 密码不再是明文了,sign值也不再是固定的了。

自定义的 jar 包,记得要在测试计划里面添加一下!

4、多接口测试

4.1、场景接口

在这里的话,设有虚拟一个场景,用的是步骤一步骤二和步骤三来代替。

它们的流程大概如下:

  1. 调用步骤一接口,会返回一个 data 字段
  2. 根据步骤一返回的 data 字段,去调用步骤二的接口,会返回一个 data 字段
  3. 根据步骤二返回的 data 字段,去调用步骤三的接口

下面是各接口定义

4.2、实际操作

步骤一

请求:

POST http://localhost:8532/auto/step1
Content-Type: application/json

{
   "str":"123",
   "r":"456"
}

响应:

{"code":0,"msg":"ok","data":"step1"}

步骤二

请求:

POST http://localhost:8532/auto/step2
Content-Type: application/json

{
   "str":"123",
   "r":"step1"
}

响应:

{"code":0,"msg":"ok","data":"step1+step2"}

步骤三

请求:

POST http://localhost:8532/auto/step3
Content-Type: application/json

{
   "str":"123",
   "r":"step1+step2"
}

响应:

{"code":0,"msg":"ok","data":"step1+step2+step3"}

4.3、步骤一处理

添加一个 HTTP 请求,进行相关的参数设定。

同时还要添加一个 JSON Extractor 的后置处理器

添加这个处理器的目的就是为了获取到接口返回的 data 字段。

这里的配置和前面的 JSON 断言其实差不多,都是定义一个参数名和 JSON 节点的路径就可以了。

到这里的话,步骤一的接口就可以了。

下面是步骤二,要怎么用步骤一返回的结果数据。

4.4、步骤二处理

步骤二也是一个 HTTP 请求,所以这里也是添加,不一样的地方是参数这一块。

可以看到,这里是直接把步骤一的 JSON Extractor 里面定义的变量名拿过来用了。

用法和参数化的方式差不多。这里继续复刻步骤一的 JSON Extractor,提取步骤三需要的内容。

4.4、步骤三处理

同样是添加一个 HTTP 请求,参数配置和步骤二类似。

换的是步骤二的变量名。

步骤三还要加一个 JSON 断言,确定返回的 data 是期望值。

到这里,有依赖性的多接口测试其实已经配置好了。

最后就是添加一个查看结果树,看对应的结果。

参考:zhuanlan.zhihu.com/p/370912804