JMeter 简单使用

Posted by pggsnap on May 18, 2018

一、测试计划

测试计划是对已配置的请求集执行的具体说明,最重要组件包括:

1. 线程组(ThreadGroup)

1 秒内创建 10 个线程,并且每个线程执行 3 次请求;如果执行失败,则终止该线程。如果所有线程都正常,则一共会执行 30 次请求。

2. 创建测试请求(Sampler 采样器)

包括 HTTP 请求、TCP 请求、JDBC 请求、AJP、JMS、JSR223、SMTP 等各种请求类型。

3. 监听器(Listeners)

监听器提供不同的方式查看由采样器请求产生的结果,以报表、树形结构、图形结构或日志文件等形式分析结果。

图中共生成了树形、图形以及表格 3 种形式来查看结果。以 Aggregate Graph 为例:

Samples:30,一共 30 个请求;

Average:31991,请求平均耗时 32s 左右;

Median:31744,有一半请求的耗时低于 31744ms;

99%Line:34853,有 99% 请求的耗时低于 34853ms;

Error%:0,所有请求都正常响应;

Throughput:18.5/min,吞吐量为每分钟可以处理 18.5 个请求。

二、测试执行次序

1. 线程组

Thread Group:并发执行 Sampler 的线程组;

setUp Thread Group:单独的一组线程,在主任务开始执行之前,用于完成一些准备工作;

tearDown Thread Group:单独的一组线程,在主任务完成之后,进行一些扫尾工作。

执行次序为:setUp Thread Group -> Thread Group -> tearDown Thread ThreadGroup

2. 元件

Pre Processors:前置处理器,可以在执行 Sampler 之前预先进行一些处理;

Post Processors:后置处理器,执行 Sampler 后进行一些处理。

元件执行次序:配置元件 Config Element -> 前置处理器 Pre Processors -> 定时器 Timer -> 取样器 Sampler -> 后置处理器 Post Processors -> 断言 Assertions -> 监听器 Listener。

3. BeanShell

JMeter 在它的 BeanShell 中内置了变量,主要如下:

  • log:日志;
  • ctx:该变量引用了当前线程的上下文;
  • vars:操作 jmeter 变量,实际引用了 jmeter 线程中的局部变量容器(本质上是 Map),常用方法:vars.get(String key),vars.put(String key, String value);
  • props:操作 jmeter 属性,该变量引用了 jmeter 的配置信息,可以获取 jmeter 属性,使用方法与 vars 类似。与 vars 最大的不同是该变量可以在线程间共享。
  • prev:获取前面 Sample 返回的信息,常用方法:getResponseDataAsString():获取响应信息;getResponseCode():获取响应 code。

示例:

定义了一个 sample 用于登陆操作,返回结果:

{
   "access_token":"2af3fbee-86fb-4408-a5d2-d9f8f764b9c2",
   "token_type":"bearer",
   "refresh_token":"3cb4ef79-806a-4ad6-8c5a-3f0e673ab6c8",
   "expires_in":42212,
   "scope":"xx"
}

通过 BeanShell PostProcessor 获取 access_token:

// 测试计划中先导入包
import org.json.JSONObject;
// 获取上一个 sample 的返回结果
String result = prev.getResponseDataAsString();
// String 转 JSONObject
JSONObject data = new JSONObject(result);
// 获取 key 为 access_token 对应的 value
String token = data.get("access_token").toString();
log.info("---------- " + token);
// 加入共享变量
props.put("access_token", token);

4. 为什么有了 Pre Processors 还需要 setUp Thread Group?

考虑一个场景,我需要压力测试一个 restful 接口 api1,测试该接口之前需要先调用另一个接口 api0 获取 access_token,之后把 access_token 放入到 api1 的 header 中去。那么,需要先执行 api0 1 次,然后 100 个线程并发执行 api1。

如果在同一个线程组中,可以先定义一个 sample0 用于执行 api0,然后定义一个 sample1 用于执行 api1,顺序执行,那么这 2 个接口都会执行 100 次。哪怕是把 sample0 封装在 Once Only Controller 下面,也无效;因为 Once Only Controller 只针对单个线程有效:即如果线程组设置了 1 个线程,循环执行 10 次,那么被 Once Only Controller 封装的 sample 只执行 1 次;如果设置了多个线程,就无能为力了。

解决方法是在 setUp Thread Group 中设置 1 个线程,执行 api0,然后把获取的 access_token 保存到 BeanShell 中的 props 变量中;之后在 Thread Group 中执行 api1,通过共享变量 props 获取 access_token 的值放入请求头中即可。

三、读取文件

测试一个接口,该接口有一个参数 bookdate,并发测试时需要从文件中读取 bookdate 的值,操作如下:

1、创建文件

everseeker@mbp $cat 7932002.csv
2017-03-30
2017-03-25
2017-03-14
2017-03-12
2017-03-18
2017-03-11
2017-03-13
2017-03-03
2017-02-27
2017-01-14
2017-01-20

2、Add -> Config Element -> CSV Data Set Config

3、设置请求参数:

参考

快速学习Jmeter性能测试工具