背景
spring boot test的项目中常用的测试框架, 最近在写集成测试的时候发现一个比较奇怪的问题,当我在运行多个测试用例的时候会偶尔重新启动整个容器上下文,由于后期业务逐渐复杂,大量的测试用例需要运行,这个问题直接导致回归测试的效率降低。
举个例子:
几个类:
@RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class BaseApiTest { @<strong>本文来源gaodai#ma#com搞@@代~&码*网2</strong>Test public void init() { } } public class ApiTest1 extends BaseApiTest { @MockBean private Service service; @Test public void test1() { service.call(); } } public class ApiTest2 extends BaseApiTest { @Autowired private Service service; @Test public void test2() { service.call(); } } @SpringBootApplication @Slf4j public class TestApplication { public static void main(String[] args) { log.info("启动容器"); new SpringApplication(TestApplication.class).run(args); } } @Component public class Service { public void call() { System.out.println("service called"); } }
运行test包下所有测试:
发现容器重复启动了。
测试用例的运行流程
可以开启idea的线程堆栈跟踪,观察整个容器的启动路径
com.intellij.rt.junit是idea内部的实现,点击idea的运行单测会触发JunitStarter的main函数去启动,可以去GitHub找到源码:
做一些准备工作找到指定的runner就开始调用junit的包去执行编写的单测,junit为了灵活的扩展不同的测试运行环境,类似SPI机制动态获取Runner去运行单测。例如我的例子里指定了SpringRunner就是需要依赖Spring容器的一个实现,这样就让测试用例可以运行在Spring环境中。
junit的入口也支持在测例前后去插入一些操作,自己去实现RunnerListener即可。junit默认实现了监听器去记录测例的耗时,失败的数量等信息。