一、入门
1. 一个最小的压测元素集合
第一次启动Jmeter界面是英文,可以options => chooseLanguage => chinese(simple)操作切换至中文
一个最简单的压测元素集合包括: 一个测试计划 一个线程组 (线程(用户)) 一个HTTP请求(取样器) 一个汇总报告(监听器)
2.简单入门demo
计划对下面接口压测,总共调用12次,4秒内完成。也就是12 / 4 = 3 ,每秒并发3个请求.
@RestController
@RequestMapping("/test")
public class TestController {
public static AtomicInteger countA = new AtomicInteger(0);
@RequestMapping("/a")
public String a(){
System.out.printf("第%d次被调用\n",countA.incrementAndGet());
return "ok";
}
}
2.1. 创建测试计划
可以理解为一个测试项目的顶层文件夹。 单击“新建”按钮,然后只需要编辑名称和注释,如下图:
2.2. 创建线程组
用于设置模拟用户的个数(),以及用户调用接口的频率。 右击“测试计划”=>“添加”=>“线程(用户)”=>“线程组”
参数设置 线程数:可以理解为用户数 Ramp-Up时间(秒):在多少秒内启动线程数设置的线程数量 循环次数:上面俩个参数规定的行为的循环次数。 按照前面的简单入门demo的测试计划,对应参数设置12,4,1就行,如图:
2.3. 创建HTTP请求
这里就是设置本次压测要调用哪个HTTP接口,也就是定义用户的行为。 右击“测试计划”=>“添加”=>“取样器”=>“HTTP请求”
设置项 “Web服务器” 协议:http 服务器名称或IP:127.0.0.1 端口号:8080 HTTP请求:GET 路径:/test/a 另外下面还可以配置接口的所需参数(本接口没有所需参数就不配置),如图:
2.4. 创建汇总报告
这是用来展示本次压测结果的
样本:表示测试中一共发出去了多少个请求 平均值:平均响应时间,默认是单个request响应时间 最小值:最短响应时间 最大值:最大响应时间 异常 %:请求失败率 吞吐量:吞吐量——默认情况下表示每秒完成的请求数(Request per Second) 接受 KB/sec:每秒钟服务器端接收请求量 发送 KB/sec:每秒钟客户端发送请求数量
2.5. 启动压测&查看汇总报告
单击"启动"按钮即可
压测结果如图,元素的基本创建已经学会,入门结束。下面开始进阶
二、进阶
1.场景一:顺序
本次用到元素组件:测试计划,线程组,取样器,监听器。
1.1. 自然顺序(从前往后依次)
场景描述:要对一个功能进行压测,这个功能涉及到二个接口:A,B。并且在调用用接口B之前,A要被先调用。A前B后. 要测试的A,B俩个接口如下:
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/a")
public String a(){
return "接口A调用成功";
}
@RequestMapping("/b")
public String b(){
return "接口B调用成功";
}
}
1.添加测试计划
2.添加线程组,设置如下参数:(1s三次请求)
3.添加HTTP请求A
4.添加HTTP请求B
5.添加查看结果树
这里重点在查看接口的调用顺序,而不关注性能,而结果树可以展示出接口的调用顺序,以及每个接口的入参与出参。
最终的一个元素结构如下:
6.运行后查看结果
可以看到满足了顺序要求,并且可以清晰的查看每个接口的请求和响应数据。
再把目录中请求A与B调换,再次运行,就发现实际调用顺序也改变了:
得出结论,左方列表的顺序 就是实际调用的顺序。
注意(拓展):在编写HTTP请求A和B的时候,发现都会重复设置一遍Web服务器项内容:
为了提高编辑效率,可以添加HTTP默认请求值,目录和参数如下:
然后再把HTTP请求AB删掉对应的Web服务器参数 再次运行,发现HTTP请求默认值组件的配置应用到了后面的HTTP请求A和B中 自然顺序到此结束.
2.场景二:HTTP请求携带参数(固定参数)
要对以下接口A压测:
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/a")
public String a(@RequestParam("userId") Integer userId,
@RequestParam("name") String name){
System.out.println(userId +" " + name);
return "ok";
}
}
第一种方案:将userId与name写死: userId=0 name=xh 如下图配置
3.场景三:HTTP请求携带参数(参数从csv文件动态读取)
首先创建csv文件,如下:
添加CSV 数据文件设置
配置如下:
最后在HTTP请求下将写死的值,用${}替换,如下:
注意左侧测试计划的顺序。CSV 数据文件设置在HTTP请求的上方
4.场景四:HTTP请求需要携带Head头部信息
接口如下:
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/a")
public String a(@RequestHeader("token") String token){
System.out.println(userId +" " + name + " " + token);
return "ok";
}
}
可以添加HTTP信息头管理器
如下配置即可
5.场景五:HTTP请求需要一个循环ID
比如ID min = 0 max =5 每次获取id时增加1,,到了max时,又从0开始递增 要实现这个需求,可以采用计时器,如下:
接口:
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/a")
public String a(@RequestParam("id") Integer token){
System.out.println(token);
return "ok";
}
}
创建计数器:
HTTP请求取值
响应时间图
图表如下:
响应断言
针对以下接口:
@RestController
@RequestMapping("/test")
public class TestController {
public static AtomicInteger m = new AtomicInteger(0);
@GetMapping("/a")
public String a(@RequestParam("id") String token){
if (m.incrementAndGet() % 2 == 0) return "ok";
return "no";
}
}
用于判断请求响应是否符合预期
结果如下:
|