这里测试的场景是秒杀优惠券的抢购,总共有200张优惠券,1000个人同时抢购,测试系统高并发下的性能。由于我是新建的系统,所以本次测试分为两步进行,第一步是生产数据,也就是让1000个用户登录登录系统,然后再用jmeter进行测试。
生产数据
该部分分成三步进行:
-
随机号码生成
-
生成1000条用户信息
-
模拟登录获取token,并将1000条token保存到.txt文件中
注意:这里只针对我设计的系统,发送验证码部分需要返回code,用于后面模拟登录,并且用户id需要连续,因为后面直接用了一个循环模拟登录,否则会报空指针异常

随机号码生成
这里需要实现一个工具类,用于实现手机号码的生成,代码如下:
package com.hmdp.utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
/**
* @author xiaoye
* @date 2023/3/10
*/
public class RandomPhoneNumber {
//手机号前三位
public static final String[] PHONE_PREFIX = {
"130", "131", "132","133","134", "135", "136", "137", "138", "139","145",
"149","150", "151", "152","153","155","156", "157", "158", "159",
"182", "183", "184", "187", "188", "178", "147", "172", "198"
};
/**
* 生成手机号
*
* @param num 生成手机号数量
*/
public static List createMobile(int num) {
List<String> phones = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < num; i++) {
StringBuilder sb = new StringBuilder();
String mobile01 = PHONE_PREFIX[random.nextInt(PHONE_PREFIX.length)];
int temp;
sb.append(mobile01);
//生成手机号后8位
for (int j = 0; j < 8; j++) {
temp = random.nextInt(10);
sb.append(temp);
}
phones.add(sb.toString());
}
return phones;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(new List[]{createMobile(10)}));
}
}
生成用户信息
进入Spring Boot下的测试类,定义一个测试方法,随后运行
@Autowired
private IUserService userService;
@Test
public void createUserBy1000(){
List<String> phones = RandomPhoneNumber.createMobile(1000);
for (String phone : phones) {
if(!RegexUtils.isPhoneInvalid(phone)){
// 1.创建用户
User user = new User();
user.setPhone(phone);
user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));
userService.save(user);
}
}
}
进入数据库,看数据是否成功生成,我的结果如下:

模拟登录获取token
这里需要用到Spring Boot中MockMvc进行单元测试,实现了对Http请求的模拟。它能够直接使用网络的形式,转换到Controller的调用,使得测试速度快、不依赖网络环境。具体的使用可以网上搜相关代码,我设计的单元测试类:
@Resource
private MockMvc mockMvc;
@Resource
private IUserService userService;
@Test
public void tokenBy1000() throws Exception {
String phone = "";
String code = "";
// 这里的路径设置为自己想要的地方
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\token.txt"));
// 模拟1000个用户登录
for (int i = 4; i < 1000; i++) {
User user = userService.getById(i);
phone = user.getPhone();
// 模仿通过手机号发送验证码
ResultActions perform = mockMvc.perform(MockMvcRequestBuilders
.post("/user/code?phone=" + phone));
// 获取Response的body信息
String resultJson = perform.andReturn().getResponse().getContentAsString();
// 转为Result对象
Result result = JSONUtil.toBean(resultJson, Result.class);
// 验证码
code = result.getData().toString();
//创建登录表单
LoginFormDTO loginFormDTO = new LoginFormDTO();
loginFormDTO.setCode(code);
loginFormDTO.setPhone(phone);
//将表单转换为json格式的字符串
String loginFormDtoJson = JSONUtil.toJsonStr(loginFormDTO);
//创建虚拟请求,模拟登录
ResultActions perform2 = mockMvc.perform(MockMvcRequestBuilders.post("/user/login")
//设置contentType表示为json信息
.contentType(MediaType.APPLICATION_JSON)
//放入json对象
.content(loginFormDtoJson));
String resultJson2 = perform2.andReturn().getResponse().getContentAsString();
Result result2 = JSONUtil.toBean(resultJson2, Result.class);
//获得token
String token = result2.getData().toString();
System.out.println(token);
//写入
osw.write(token+"\n");
}
// 关闭输出流
osw.close();
}
注意:测试类外面需要使用@AutoConfigureMockMvc注解开启MockMvc
jmeter测试配置
以上准备工作做好,我们就可以用jmeter进行测试
线程组配置

HTTP请求设置

请求头设置

CSV数据文件设置

JSON断言设置

最后添加一些监听器,并进行测试,测试结果如下
