SpringBoot环境下junit单元测试速度优化

1、提高单元测试效率背景:在项目提测前,自己需要对代码逻辑进行验证,所以单元测试必不可少。但是现在的java项目几乎都是基于SpringBoot系列开发的,所以在进行单元测试时,执行一个测试类就要启动springboot项目,加载上下文数据,每次执行一次测试都要再重新加载上下文环境,这样就会很麻烦,浪费时间;在一次项目中,我们使用自己的技术框架进行开发,每次单元测试时都要初始化很多数据(例如根据数据模型建立表,加载依赖其它模块的类),这样导致每一次单元测试时都会花3-5分钟时间(MacOs 四核I
摘要由CSDN通过智能技术生成

1、提高单元测试效率

  • 背景:在项目提测前,自己需要对代码逻辑进行验证,所以单元测试必不可少。但是现在的java项目几乎都是基于SpringBoot系列开发的,
    所以在进行单元测试时,执行一个测试类就要启动springboot项目,加载上下文数据,每次执行一次测试都要再重新加载上下文环境,这样
    就会很麻烦,浪费时间;在一次项目中,我们使用自己的技术框架进行开发,每次单元测试时都要初始化很多数据(例如根据数据模型建立表,
    加载依赖其它模块的类),这样导致每一次单元测试时都会花3-5分钟时间(MacOs 四核Intel Core i5 内存:16g),所以很有必要
    优化单元测试效率,节约开发时间。

2、单元测试如何执行

  • 首先要优化单元测试,那要知道单元测试是怎样执行的
  • 引入相关测试的maven依赖,例如junit,之后在测试方法加上@Test注解即可,在springboot项目测试中还需要在测试类加上@RunWith注解
    然后允许需要测试的方法即可

补充说明
@RunWith 就是一个运行器
@RunWith(JUnit4.class) 就是指用JUnit4来运行
@RunWith(SpringJUnit4ClassRunner.class),让测试运行于Spring测试环境
@RunWith(Suite.class) 的话就是一套测试集合,
@ContextConfiguration Spring整合JUnit4测试时,使用注解引入多个配置文件@RunWith

SpringBoot环境下单元测试一般是加@RunWith(SpringJUnit4ClassRunner.class)注解,SpringJUnit4ClassRunner继承BlockJUnit4ClassRunner类,
然后在测试方式时会执行SpringJUnit4ClassRunner类的run方法(重写了BlockJUnit4ClassRunner的run方法),
run方法主要是初始化spring环境数据,与执行测试方法

3、项目中使用

  • 在我们项目中,是通过一个RewriteSpringJUnit4ClassRunner类继承SpringJUnit4ClassRunner,然后@RunWith(RewriteSpringJUnit4ClassRunner.class)来初始化我们框架中需要的数据,
    RewriteSpringJUnit4ClassRunner里面是通过重写withBefores方法,在withBefores方法中去初始化数据的,之后通过run方法最后代理执行测试方法

4、优化单测思路

  • 通过上面说明,可以知道每次测试一个方法都要初始化springboot环境与加载自己框架的数据,所以有没有一种方式可以只需要初始化
    一次数据,就可以反复运行测试的方法呢?

思路:首先每一次单测都需要重新加载数据,跑完一次程序就结束了,所以每次测试方法时都要重新加载数据,
如果只需要启动一次把环境数据都加载了,然后之后都单元测试方法都使用这个环境呢那不就能解决这个问题么。
我们是不是可以搞一个服务器,把基础环境与数据都加载进去,然后每次执行单元测试方法时,通过服务器代理去执行这个方法,不就可以了吗

5、实现方式

  • 首先我们可以用springboot的方式启动一个服务,通常使用的内置tomcat作为服务启,之后暴露一个http接口,入参为需要执行的类和方法,
    然后通过反射去执行这个方法;还可以通过启动jetty服务,通过jetty提供的handler处理器就可以处理请求,jetty相对于tomcat处理请求更加
    方便
  • 服务是有了,那怎样将单元测试方法代理给服务器呢?前面提到过,通过@RunWith注入的类,在单元测试方法运行时会执行@RunWith注入的类相应
    的方法,所以我们可以在@RunWith注入的类里面做文章,拿到测试类与方法,然后通过http访问服务器,然后服务器去代理执行测试方法

6、编码实现

  • 下面将通过两种不同方式实现,以Jetty为服务器启动,与以Tomcat为服务器启动

6.1 Jetty作为服务启动

  • 首先编写服务启动类,并在spring容器准备好后加载我们公司框架相关数据,这里使用jetty作为服务器,下面代码是核心方法
// 只能写在测试目录下,因为写在应用程序目录下在序列化时,找不到测试目录下的类-》InvokeRequest类中的Class<?> testClass反序列化不出来
@SpringBootApplication
@ComponentScan(value = "包路径")
public class DebugRunner {

    public static void main(String... args) {
        SpringApplication.run(DebugRunner.class, args);
        System.out.println("================================success========================");
    }

    @EventListener
    public void onReady(ContextRefreshedEvent ev
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值