# cat2bug-junit
**Repository Path**: cat2bug/cat2bug-junit
## Basic Information
- **Project Name**: cat2bug-junit
- **Description**: 这是一个基于springboot单元测试的项目,用于自动测试接口功能,并可以提交到cat2bug-platform平台
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: master
- **Homepage**: https://www.cat2bug.com
- **GVP Project**: No
## Statistics
- **Stars**: 9
- **Forks**: 5
- **Created**: 2024-02-25
- **Last Updated**: 2025-06-18
## Categories & Tags
**Categories**: testing
**Tags**: JUnit, 单元测试, Java, test, SpringBoot
## README
# Cat2Bug-Spring-Boot-JUnit
## 介绍
[Cat2Bug-Spring-Boot-JUnit](https://gitee.com/cat2bug/cat2bug-spring-boot-junit) 是[Cat2Bug](https://www.cat2bug.com) 推出的Java Spring单元测试功能包,目标是通过一两行代码的编写,完成整个项目的单元测试,减少开发人员在单元测试过程中的维护成本,提高项目管理质量及效率。
## 理念
减少单元测试维护成本、减少开发人员学习时间,更快的发现系统缺陷。如果您可以耐心看完我们的介绍,那么您就会发现今后的所有项目,将在分分钟内解决单元测试的工作。
## 连接
* 官网: https://www.cat2bug.com
* library github: https://github.com/cat2bug/cat2bug-junit
* library gitee: https://gitee.com/cat2bug/cat2bug-junit
## 软件架构
Cat2Bug-Spring-Boot-JUnit 以Spring Boot 2、JUnit 4 为基础,添加测试报告推送、扫包自动创建测试类功能,使开发人员可以通过添加简单注解快速进行单元测试。

## 运行流程

## 优势与特点
* 目前世面上唯一一种SpringBoot自动化单元测试框架
* 极大减少单元测试的维护时间和成本,基本可以将单元测试成本降为零,可以做到1分钟的代码编写,测试几百个接口。
* 基于Cat2Bug生态圈中,可以结合[Cat2Bug-Platform](https://gitee.com/cat2bug/cat2bug-platform)平台管理Bug的生命周期,通过多样性的可视化报表辅助项目经理了解系统的实时状态。
## 安装
* Gradle
```javascript
testImplementation ("com.cat2bug:cat2bug-spring-boot-junit:0.0.5")
```
* Maven
```xml
com.cat2bug
cat2bug-spring-boot-junit
0.0.5
test
```
## 在Cat2Bug生态下使用
目前[Cat2Bug-Spring-Boot-JUnit](https://gitee.com/cat2bug/cat2bug-spring-boot-junit)可以结合[Cat2Bug-Platform](https://gitee.com/cat2bug/cat2bug-platform)平台无缝联合使用,
[Cat2Bug-Spring-Boot-JUnit](https://gitee.com/cat2bug/cat2bug-spring-boot-junit)负责单元测试,并将测试后的报告通过Open API推送到[Cat2Bug-Platform](https://gitee.com/cat2bug/cat2bug-platform)平台,
[Cat2Bug-Platform](https://gitee.com/cat2bug/cat2bug-platform)平台则用于管理报告中的缺陷,并可导出相关测试报告,其生态架构如下:

### Cat2Bug-Platform环境的创建
如果需要在单元测试完成后,将测试失败的缺陷结果提交到BUG系统,需先部署[Cat2Bug-Platform](https://gitee.com/cat2bug/cat2bug-platform)平台,并设置API KEY,以下介绍一种快速部署方式,更多详情请参阅[Cat2Bug官网文档](https://www.cat2bug.com)。
1. Docker下载[Cat2Bug-Platform](https://hub.docker.com/r/cat2bug/cat2bug-platform)容器并部署,执行代码如下:
````
docker run -it -d -p 8022:8022 --name cat2bug-platform cat2bug/cat2bug-platform:latest
````
启动成功后,在浏览器访问http://127.0.0.1:8022, 如果可以正常访问,代表平台启动成功;
2. 在[Cat2Bug-Platform](https://gitee.com/cat2bug/cat2bug-platform)平台,依次注册用户,创建团队,创建项目后,在项目设置的API KEY中,添加一个KEY,用于单元测试提交报告的鉴权用,界面如下:

至此,[Cat2Bug-Platform](https://gitee.com/cat2bug/cat2bug-platform)环境已经创建完成。
## 使用说明
### 使用前注意事项
由于[Cat2Bug-Spring-Boot-JUnit](https://gitee.com/cat2bug/cat2bug-spring-boot-junit)是通过反射机制动态创建的测试类,而所用反射到的Java类库在JDK9+版本以上都必须显式的手动开启,
因此在执行测试的时候,需要手动添加启动参数,以下已IDEA编辑器、JDK17为例,添加参数如下图:

如不加以上红框的饿配置,执行时会报找不到某些类的错误,我们也可以根据提示添加缺少的类包,Java8不会出现此问题。
### 测试所有接口
与JUnit测试相同,在Spring工程中创建测试类,代码如下:
````java
@SpringBootTest
@RunWith(Cat2BugAutoSpringSuite.class)
@AutoTestScan(packageName = "com.cat2bug.junit.demo.controller")
public class Cat2bugSpringBootDemoApplicationTests {
// 不用写任何代码
}
````
* @SpringBootTest:为Spring测试注解;
* @RunWith(Cat2BugAutoSpringSuite.class):为使用Cat2Bug的套件测试;
* @AutoTestScan(packageName = "com.cat2bug.junit.demo.controller"):需要扫描的包路径;
通过添加以上三个注解,即可自动扫描测试所有工程中的接口,所有状态码返回200的接口认定为通过测试,测试结果将形成报告,打印在控制面板中,如下图:

### 为指定接口设置请求参数
目前[Cat2Bug-Spring-Boot-JUnit](https://gitee.com/cat2bug/cat2bug-spring-boot-junit)是给所有接口设置随机值进行测试的,我们也提供了RandomParameter注解为特定接口进行自定义参数的设置。示例如下:
````java
@SpringBootTest
@RunWith(Cat2BugAutoSpringSuite.class)
@AutoTestScan(packageName = "com.cat2bug.junit.demo.controller")
@Transactional
public class Cat2bugSpringBootDemoApplicationTests {
/**
* 为UserController的updateUser方法设置用户参数
* @param userRepository JAP的用户操作类
* @return 传给updateUser接口的用户实例
*/
@RandomParameter(className = "com.cat2bug.junit.demo.controller.UserController", methodName = "updateUser", parameterName = "user")
public User insertUser(
@Autowired UserRepository userRepository
) {
User user = new User(1L,"admin","cat2bug");
return userRepository.save(user);
}
/**
* 设置所有接口方法包含Id的参数值。
*
* @return 用户ID
*/
@RandomParameter(parameterName = ".*Id.*")
public long userId() {
return 1L;
}
/**
* 设置参数名等于name的值。
*
* @return
*/
@RandomParameter(parameterName = "name")
public String name() {
String[] names = { "唐玄奘", "孙悟空", "猪八戒", "沙悟净" };
return names[(int) (Math.random() * names.length)];
}
}
````
注意:RandomParameter注解的方法不能调用本类的其它方法或全局变量,因为这些带有RandomParameter方法会复制到临时的测试类中,而方法外的其它方法或属性不会被复制。
### 基于Spring Security的测试
在大部分的软件工程中,接口都会受权限控制,因此,在[Cat2Bug-Spring-Boot-JUnit](https://gitee.com/cat2bug/cat2bug-spring-boot-junit)中也提供了相应的解决方案,实现代码如下:
````java
@SpringBootTest
@RunWith(Cat2BugAutoSpringSuite.class)
@AutoTestScan(packageName = "com.cat2bug.junit.demo.controller")
@Authentication(name = "admin",password = "cat2bug")
public class Cat2bugSpringBootDemoApplicationTests {
// 不用写任何代码
}
````
此方式提供的Authentication注解,用于在测试类中自动注入用户权限,其属性说明如下:
* name:系统用户账户
* password:系统用户密码
除了标准的通过注解方式鉴权之外,由于一些系统自定义处理了用户权限,因此,也可以实现一个方法用来自定义权限,代码如下:
````java
@SpringBootTest
@RunWith(Cat2BugAutoSpringSuite.class)
@AutoTestScan(packageName = "com.cat2bug.junit.demo.controller")
public class Cat2bugSpringBootDemoApplicationTests {
@Autowired
public void Security(AuthenticationManager authenticationManager) {
// 以下是标准赋权方式,用户可根据自己需求编写代码
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken("admin", "cat2bug");
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(authenticationManager.authenticate(authenticationToken));
SecurityContextHolder.setContext(securityContext);
}
}
````
通过以上两种方式中的任意一种,即可获取权限测试接口。
### 报告推送到Cat2Bug-Platform平台
在测试完成后,可将测试报告推送到Bug管理平台,执行代码如下:
````java
@SpringBootTest
@RunWith(Cat2BugAutoSpringSuite.class)
@AutoTestScan(packageName = "com.cat2bug.junit.demo.controller")
@PushReport(host = "http://127.0.0.1:8022", projectKey = "20240225012438h19zzdb6sd1ahazj", handler = "admin", type = "all", version = "0.0.3")
public class Cat2bugSpringBootDemoApplicationTests {
// 不用写任何代码
}
````
PushReport注解即推送数据之用,其参数功能如下:
* host:接口地址;
* projectKey:在Cat2Bug-Platform中创建的Open API密钥;
* handler:缺陷处理人,Cat2Bug-Platform中用户的登陆账号;
* type:提交的类型,all为成功失败都提交,defect为只提交失败的缺陷;
* version:测试的工程版本
除此之外,host、projectKey、handler属性也可以在SpringBoot的application.yml中设置,配置如下:
````yaml
cat2bug:
junit:
push-report:
host: http://127.0.0.1:2020/
project-key: 2024032722581018ubh4nfreu1vqse
handler: demo
type: all
version: 0.0.3
````
注意:注解的属性值优先于application.yml中的值,单元测试执行完成后,会在命令行中显示推送成功的信息。
````shell
Title: 提交测试报告
推送地址:http://127.0.0.1:8022/api/report/defect
处理人:admin
推送报告成功
````
Cat2Bug-Platform平台接收到的报告显示如下:

## 报告
[Cat2Bug-Spring-Boot-JUnit](https://gitee.com/cat2bug/cat2bug-spring-boot-junit)中提供了多种类型的报告:
* 编译类报告:统计自动化扫描到的接口,并编译生测试类是否成功的报告;
* 测试类报告:统计每个测试类成功、失败的数据总和;
* 测试接口报告:显示每个接口测试相关信息的报告;
* HTML报告:以Html文件形式显示的报告,文件输出到工程编译目录,默认为target目录;
* 推送报告:推送到Cat2Bug-Platform的报告;
## API说明
### AutoTestScan 类注解
**用能:**
用于指定自动测试哪些包下的Controller类。
**参数说明:**
| 参数名 | 类型 | 是否必填 | 功能描述 |
|---|---|---|---|
| packageName | 字符串 | 是 | 指定扫描的包名称。 |
### PushReport 类注解
**用能:**
在测试完成后,将失败的测试结果发送到[Cat2Bug-Platform](https://gitee.com/cat2bug/cat2bug-platform)。
**参数说明:**
| 参数名 | 类型 | 是否必填 | 功能描述 |
|------------|-----|------|--------------------------------------------------------------------|
| host | 字符串 | 是 | Cat2Bug-Platform平台的网址。 |
| projectKey | 字符串 | 是 | 应用配置中的Key。 |
| handler | 字符串 | 是 | 在Cat2Bug-Platform平台注册的用户登陆名。 |
| type | 字符串 | 是 | 推送报告的类型,all:推送所有成功和失败的数据(推送成功报告的原因是可以自动关闭之前错误的缺陷)、defect:只推送失败的报告。 |
| version | 字符串 | 是 | 测试的系统版本。 |
| isPush | 布尔型 | 否 | 是否推送问题报告到[Cat2Bug云平台](https://www.cat2bug.com),默认值为true推送。 |
### RandomParameter 方法注解
**用能:**
此注解需要与@RunWith(Cat2BugAutoSpringSuite)一起配合使用,Cat2BugAutoSpringSuite类用来扫描功能类后动态创建测试用例,RandomParameter用于赋值某个测试方法的参数值。当用户没有实现RandomParameter时,测试方法的参数会根据数据类型随机赋值。
**参数说明:**
| 参数名 | 类型 | 是否必填 | 功能描述 |
|---------------|-------|------|----------------------------------------|
| className | 正则表达式 | 否 | 指明哪个测试类名接收此方法的返回值,如果为空,代表所有测试类都接收此值。 |
| methodName | 正则表达式 | 否 | 指明哪个测试方法名接收此方法的返回值,如果为空,代表所有测试方法都接收此值。 |
| parameterName | 正则表达式 | 是 | 指明测试方法中的哪个参数名接收此方法的返回值。 |
在测试一些业务功能时,如删除指定Id的数据信息,这时需要传递指定的Id值做为参数,采用随机赋值测试的方法就行不通了,此时就可以通过RandomParameter注解,指定哪一个测试类、哪一个测试方法的哪个参数来返回这个固定Id值。
另外需要注意RandomParameter注解的方法必须有返回值。
### Cat2BugRunner 类
Cat2BugRunner注解继承于BlockJUnit4ClassRunner类,主要功能用于非Spring工程的测试类。
```java
@RunWith(Cat2BugRunner.class)
@PushReport(host = "http://127.0.0.1:8022", projectKey = "********-****-****-****-********", handler="处理用户登陆名")
public class Cat2BugRunnerTest {
@Test
public void testFalse() {
Assert.assertTrue(false);
}
}
```
### Cat2BugSpringRunner 类
Cat2BugSpringRunner继承于SpringJUnit4ClassRunner类,功能与Cat2BugRunner类相同,主要用于单个测试类。
```java
@RunWith(Cat2BugSpringRunner.class)
@PushReport(host = "http://127.0.0.1:8022", projectKey = "********-****-****-****-********",handler="处理用户登陆名")
@WebAppConfiguration
@SpringBootTest
public class Cat2BugSpringRunnerTest {
private MockMvc mock;
@Autowired
private WebApplicationContext webContext;
@Before
public void init() {
mock = org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup(webContext).build();
}
@Test
public void testGetAllUsers() throws Exception {
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/users")
.contentType(MediaType.APPLICATION_JSON);
mock.perform(builder).andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn().getResponse().getContentAsString();
}
}
```
### Cat2BugAutoSpringSuite 类
Cat2BugAutoSpringSuite继承于Suite套件类,此类是[Cat2Bug-Spring-Boot-JUnit](https://gitee.com/cat2bug/cat2bug-spring-boot-junit)的灵魂类,用于自动测试所有接口,它在启动时会扫描Java包中的Controller层,动态创建Controller测试类,将其中带有GetMapping、PostMapping、PutMapping、DeleteMapping、RequestMapping注解的方法自动生成测试方法进行单元测试。
```java
@RunWith(Cat2BugAutoSpringSuite.class)
@AutoTestScan(packageName = "com.cat2bug.junit.demo")
@PushReport(host = "http://127.0.0.1:8022", projectKey = "********-****-****-****-********", handler="处理用户登陆名")
@Transactional
public class Cat2BugJunitDemoApplicationTests {
/**
* 计算接口方法中,参数名包含Id的字符型的返回值。
*
* @return
*/
@RandomParameter(parameterName = ".*Id.*")
public String userId() {
return UUID.randomUUID().toString();
}
/**
* 计算接口方法中,参数名等于name的的返回值。
*
* @return
*/
@RandomParameter(parameterName = "name")
public String name() {
String[] names = { "唐玄奘", "孙悟空", "猪八戒", "沙悟净" };
return names[(int) (Math.random() * names.length)];
}
}
```
相关测试Demo,请参阅源代码中cat2bug-spring-boot-demo工程。
## 未来计划
目前[Cat2Bug-Spring-Boot-JUnit](https://gitee.com/cat2bug/cat2bug-spring-boot-junit)还在持续成长中,后续我们将在代码质量、性能、安全等几个方向持续投入,完善框架的功能。2024计划如下:
* 丰富多维度的测试报告;
* 添加自动化性能测试;
* 添加自动化代码质量检测;
## Cat2Bug交流群
| QQ群: [731462000](https://qm.qq.com/cgi-bin/qm/qr?k=G_vJa478flcFo_1ohJxNYD0mRKafQ7I1&jump_from=webapi&authKey=EL0KrLpnjYWqNN9YXTVksNlNFrV9DHYyPMx2RVOhXqLzfnmc+Oz8oQ38aBOGx90t) | 微信群:Cat2Bug |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------|
|
|
|