Cat2Bug-Spring-Boot-JUnit 是Cat2Bug 推出的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平台管理Bug的生命周期,通过多样性的可视化报表辅助项目经理了解系统的实时状态。
- Gradle
testImplementation ("com.cat2bug:cat2bug-spring-boot-junit:0.0.5")
- Maven
<dependency>
<groupId>com.cat2bug</groupId>
<artifactId>cat2bug-spring-boot-junit</artifactId>
<version>0.0.5</version>
<scope>test</scope>
</dependency>
目前Cat2Bug-Spring-Boot-JUnit可以结合Cat2Bug-Platform平台无缝联合使用, Cat2Bug-Spring-Boot-JUnit负责单元测试,并将测试后的报告通过Open API推送到Cat2Bug-Platform平台, Cat2Bug-Platform平台则用于管理报告中的缺陷,并可导出相关测试报告,其生态架构如下:
如果需要在单元测试完成后,将测试失败的缺陷结果提交到BUG系统,需先部署Cat2Bug-Platform平台,并设置API KEY,以下介绍一种快速部署方式,更多详情请参阅Cat2Bug官网文档。
- Docker下载Cat2Bug-Platform容器并部署,执行代码如下:
docker run -it -d -p 8022:8022 --name cat2bug-platform cat2bug/cat2bug-platform:latest
启动成功后,在浏览器访问http://127.0.0.1:8022, 如果可以正常访问,代表平台启动成功;
- 在Cat2Bug-Platform平台,依次注册用户,创建团队,创建项目后,在项目设置的API KEY中,添加一个KEY,用于单元测试提交报告的鉴权用,界面如下:
至此,Cat2Bug-Platform环境已经创建完成。
由于Cat2Bug-Spring-Boot-JUnit是通过反射机制动态创建的测试类,而所用反射到的Java类库在JDK9+版本以上都必须显式的手动开启, 因此在执行测试的时候,需要手动添加启动参数,以下已IDEA编辑器、JDK17为例,添加参数如下图:
如不加以上红框的饿配置,执行时会报找不到某些类的错误,我们也可以根据提示添加缺少的类包,Java8不会出现此问题。
与JUnit测试相同,在Spring工程中创建测试类,代码如下:
@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是给所有接口设置随机值进行测试的,我们也提供了RandomParameter注解为特定接口进行自定义参数的设置。示例如下:
@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方法会复制到临时的测试类中,而方法外的其它方法或属性不会被复制。
在大部分的软件工程中,接口都会受权限控制,因此,在Cat2Bug-Spring-Boot-JUnit中也提供了相应的解决方案,实现代码如下:
@SpringBootTest
@RunWith(Cat2BugAutoSpringSuite.class)
@AutoTestScan(packageName = "com.cat2bug.junit.demo.controller")
@Authentication(name = "admin",password = "cat2bug")
public class Cat2bugSpringBootDemoApplicationTests {
// 不用写任何代码
}
此方式提供的Authentication注解,用于在测试类中自动注入用户权限,其属性说明如下:
- name:系统用户账户
- password:系统用户密码
除了标准的通过注解方式鉴权之外,由于一些系统自定义处理了用户权限,因此,也可以实现一个方法用来自定义权限,代码如下:
@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);
}
}
通过以上两种方式中的任意一种,即可获取权限测试接口。
在测试完成后,可将测试报告推送到Bug管理平台,执行代码如下:
@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中设置,配置如下:
cat2bug:
junit:
push-report:
host: http://127.0.0.1:2020/
project-key: 2024032722581018ubh4nfreu1vqse
handler: demo
type: all
version: 0.0.3
注意:注解的属性值优先于application.yml中的值,单元测试执行完成后,会在命令行中显示推送成功的信息。
Title: 提交测试报告
推送地址:http://127.0.0.1:8022/api/report/defect
处理人:admin
推送报告成功
Cat2Bug-Platform平台接收到的报告显示如下:
Cat2Bug-Spring-Boot-JUnit中提供了多种类型的报告:
- 编译类报告:统计自动化扫描到的接口,并编译生测试类是否成功的报告;
- 测试类报告:统计每个测试类成功、失败的数据总和;
- 测试接口报告:显示每个接口测试相关信息的报告;
- HTML报告:以Html文件形式显示的报告,文件输出到工程编译目录,默认为target目录;
- 推送报告:推送到Cat2Bug-Platform的报告;
用能:
用于指定自动测试哪些包下的Controller类。
参数说明:
参数名 | 类型 | 是否必填 | 功能描述 |
---|---|---|---|
packageName | 字符串 | 是 | 指定扫描的包名称。 |
用能:
在测试完成后,将失败的测试结果发送到Cat2Bug-Platform。
参数说明:
参数名 | 类型 | 是否必填 | 功能描述 |
---|---|---|---|
host | 字符串 | 是 | Cat2Bug-Platform平台的网址。 |
projectKey | 字符串 | 是 | 应用配置中的Key。 |
handler | 字符串 | 是 | 在Cat2Bug-Platform平台注册的用户登陆名。 |
type | 字符串 | 是 | 推送报告的类型,all:推送所有成功和失败的数据(推送成功报告的原因是可以自动关闭之前错误的缺陷)、defect:只推送失败的报告。 |
version | 字符串 | 是 | 测试的系统版本。 |
isPush | 布尔型 | 否 | 是否推送问题报告到Cat2Bug云平台,默认值为true推送。 |
用能:
此注解需要与@RunWith(Cat2BugAutoSpringSuite)一起配合使用,Cat2BugAutoSpringSuite类用来扫描功能类后动态创建测试用例,RandomParameter用于赋值某个测试方法的参数值。当用户没有实现RandomParameter时,测试方法的参数会根据数据类型随机赋值。
参数说明:
参数名 | 类型 | 是否必填 | 功能描述 |
---|---|---|---|
className | 正则表达式 | 否 | 指明哪个测试类名接收此方法的返回值,如果为空,代表所有测试类都接收此值。 |
methodName | 正则表达式 | 否 | 指明哪个测试方法名接收此方法的返回值,如果为空,代表所有测试方法都接收此值。 |
parameterName | 正则表达式 | 是 | 指明测试方法中的哪个参数名接收此方法的返回值。 |
在测试一些业务功能时,如删除指定Id的数据信息,这时需要传递指定的Id值做为参数,采用随机赋值测试的方法就行不通了,此时就可以通过RandomParameter注解,指定哪一个测试类、哪一个测试方法的哪个参数来返回这个固定Id值。
另外需要注意RandomParameter注解的方法必须有返回值。
Cat2BugRunner注解继承于BlockJUnit4ClassRunner类,主要功能用于非Spring工程的测试类。
@RunWith(Cat2BugRunner.class)
@PushReport(host = "http://127.0.0.1:8022", projectKey = "********-****-****-****-********", handler="处理用户登陆名")
public class Cat2BugRunnerTest {
@Test
public void testFalse() {
Assert.assertTrue(false);
}
}
Cat2BugSpringRunner继承于SpringJUnit4ClassRunner类,功能与Cat2BugRunner类相同,主要用于单个测试类。
@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继承于Suite套件类,此类是Cat2Bug-Spring-Boot-JUnit的灵魂类,用于自动测试所有接口,它在启动时会扫描Java包中的Controller层,动态创建Controller测试类,将其中带有GetMapping、PostMapping、PutMapping、DeleteMapping、RequestMapping注解的方法自动生成测试方法进行单元测试。
@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还在持续成长中,后续我们将在代码质量、性能、安全等几个方向持续投入,完善框架的功能。2024计划如下:
- 丰富多维度的测试报告;
- 添加自动化性能测试;
- 添加自动化代码质量检测;
QQ群: 731462000 | 微信群:Cat2Bug |
---|---|