对spring boot项目的接口测试和并发测试
一、接口测试工具swagger
-
swagger是什么?
Swagger是一组围绕 OpenAPI 规范构建的开源工具,可帮助您设计、构建、记录和使用 REST API。主要的 Swagger 工具包括:Swagger Editor – 基于浏览器的编辑器,您可以在其中编写 OpenAPI 规范。Swagger UI – 将 OpenAPI 规范呈现为交互式 API 文档。swagger2于17年停止维护,现在最新的版本为 Swagger3(Open Api3)。
-
knife4j(swagger的本地增强解决方案)
Knife4j是一个集Swagger2 和 OpenAPI3 为一体的增强解决方案,Knife4j · 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j (xiaominfo.com)
-
knife4j与springboot的兼容性
Spring Boot版本 Knife4j Swagger2规范 Knife4j OpenAPI3规范 1.5.x~2.0.0 <Knife4j 2.0.0 >=Knife4j 4.0.0 2.0~2.2 Knife4j 2.0.0 ~ 2.0.6 >=Knife4j 4.0.0 2.2.x~2.4.0 Knife4j 2.0.6 ~ 2.0.9 >=Knife4j 4.0.0 2.4.0~2.7.x >=Knife4j 4.0.0 >=Knife4j 4.0.0 >= 3.0 >=Knife4j 4.0.0 >=Knife4j 4.0.0 -
引入依赖
<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi2-spring-boot-starter</artifactId> <version>4.1.0</version> </dependency>
-
配置
knife4j: enable: true #此项必配置,否则knife4j运行有问题 openapi: title: knife4j项目的名称 description: knife4j项目的描述 email: 项目邮箱 concat: 贡献者名称 url: 项目的地址 license: Apache 2.0 license-url: http://www.apache.org/licenses/LICENSE-2.0 terms-of-service-url: https://www.bilibili.com/video/BV1tK411y7Uf/
-
常用注解
-
在返回对象上使用
在HttpResp(用户封装返回对象的类)
序列 注解 作用 1 @ApiModel 用对象来接收参数 2 @ApiModelProperty 用对象接收参数时,描述对象的一个字段 -
在Controller类和方法上使用
序列 注解 作用 1 @Api(tags = “Knife4jController接口类”) 2 @Api 修饰整个类,描述api(Controller)的作用 3 @ApiOperation 描述一个类的一个方法,或者说一个接口 4 @ApiImplicitParam 多个请求参数的描述信息 5 @ApiImplicitParam(name = “name”,value=”请求的名称”,required = true) 单个参数的描述信息 6 @ApiIgnore 使用该注解忽略这个API 7 @ApiError 发生错误返回的信息 -
@ApilmplicitParm的属性
序列 属性 值 作用 1 paramType 查询参数类型 path 以地址形式提交数据 query 直接跟参数完成映射赋值 body 以流的形式提交 仅支持POST header 参数在request headers里面提交 form 以form表单的形式提交,仅支持POST 2 dataType 参数的数据类型 只为标志说明 并没有实际验证 Long String 3 name 接收参数名 4 value 接收参数的意义描述 5 required 参数是否必填 true 必填 false 非比填 6 defaultValue 默认值
-
-
项目案例
-
目录结构
-
响应信息HttpResp类
//在common模块里 @Data @AllArgsConstructor @NoArgsConstructor public class HttpResp<T> { private int code; private String msg; private T result; private LocalDate time; }
-
实体类Type
//在domain模块里 @Data @AllArgsConstructor @NoArgsConstructor public class Type { private Integer id; private String name; private String createBy; private Date createTime; private Date updateTime; }
-
pom.xml(book-bk)配置依赖
<dependency> <groupId>com.wnhz.swagger.common</groupId> <artifactId>book-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.wnhz.swagger.domain</groupId> <artifactId>book-domain</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi2-spring-boot-starter</artifactId> <version>4.1.0</version> </dependency>
-
application.yml配置开启knife4j
#application.yml spring: profiles: active: dev
#application-dev.yml server: port: 9091 knife4j: enable: true logging: level: com.wnhz.swagger.book: debug
-
编写Controller类
@Api(tags = "图书类型接口") @RestController @RequestMapping("/api/type") @Slf4j public class TypeController { }
-
无参方法
@ApiOperation(value = "findAll", notes = "对所有图书类型查询") @GetMapping("/findAll") public HttpResp<List<Type>> findAll() { List<Type> list = new ArrayList<>(20);//默认10,不够每次扩容1.5倍 for (int i = 1; i <=100 ; i++) { list.add(new Type(i, "type_"+i, "admin", new Date(), new Date())); } log.debug("查询所有图书类型数量为:{}", list.size()); return new HttpResp<>(200, "success", list, LocalDate.now()); }
-
有参方法
@ApiOperation(value = "addType", notes = "添加新图书类型接口") @ApiImplicitParams( { @ApiImplicitParam(name = "name", value = "请输入新图书类型名称", required = true) } ) @PostMapping("/addType") public HttpResp<String> addType(String name) { log.debug("添加新的类型:{}", name); return new HttpResp<>(200, "success", null, LocalDate.now()); }
-
带上传参数的方法
@ApiOperation(value = "uploadExcel", notes = "上传excel文件进行解析接口") @ApiImplicitParams( { @ApiImplicitParam(value = "上传文件", required = true) } ) @PostMapping("/uploadExcel") public HttpResp<String> uploadExcel(@RequestPart @RequestParam("excel") MultipartFile excel) { String originalFilename = excel.getOriginalFilename(); log.debug("上传文件名称:{}", originalFilename); return new HttpResp<>(200, "success", originalFilename+"上传成功", LocalDate.now()); }
-
启动项目,在浏览器输入http://localhost:9091/doc.html
-
测试无参方法findAll
-
测试有参方法addType
-
测试带上传参数方法uploadExcel
-
还可以下载测试的离线文档
-
二、并发测试工具jmeter
-
jmeter介绍
JMeter是一个用于性能测试和负载测试的开源工具。它可以模拟多个用户同时访问一个网站、应用程序或服务,并测量其性能和稳定性。
-
下载和安装
JMeter官方网站(https://jmeter.apache.org/)下载JMeter,并按照官方文档中的说明进行安装
-
简单使用
-
修改findAll方法(加上synchronized可以解决多线程下数据不一致的问题,但会牺牲些许性能)
private int total = 1; @ApiOperation(value = "findAll", notes = "对所有图书类型查询") @GetMapping("/findAll") public synchronized HttpResp<Integer> findAll() { total = total + 1; log.debug("当前total-->:{}", total); return new HttpResp<>(200, "success", total, LocalDate.now()); }
-
添加HTTP请求
-
添加线程组
-
运行并查看结果树
-