Junit 源码解析(一)

本文解析了 JUnit 的运行容器 Runner 类,介绍了其作为单元测试执行环境的重要性,并详细阐述了 IgnoredBuilder、AnnotatedBuilder、JUnit3Builder 和 JUnit4Builder 等不同类型的运行器及其作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Junit 源码解析(一)之junit运行容器

package org.junit.runner;
public abstract class Runner implements Describable
Runner是JUNIT的运行容器,它是各种Junit运行容器的父类。我们可以把它理解成web容器,spring容器,就是单元测试类所在运行环境。
我们在跑单元测试时,单元测试用例的生命周期就是由runner来控制的。这和其他容器一样。

首先是选择容器,在跑单元测试时,最先构建的是Runner容器。源代码如下:
见AllDefaultPossibilitiesBuilder下的public Runner runnerForClass(Class<?> testClass) throws Throwable

@Override
public Runner runnerForClass(Class<?> testClass) throws Throwable {
List<RunnerBuilder> builders= Arrays.asList(
ignoredBuilder(),
annotatedBuilder(),
suiteMethodBuilder(),
junit3Builder(),
junit4Builder());

for (RunnerBuilder each : builders) {
Runner runner= each.safeRunnerForClass(testClass);
if (runner != null)
return runner;
}
return null;
}


builders是容器的创建者,它是一个list,创建ignoredBuilder(),annotatedBuilder(),suiteMethodBuilder(),junit3Builder(),junit4Builder());
遍历builders,因为list是有序的,当某一个junit容器创建成功,则跳出循环,不再创建其他容器。而创建好的Runner容器就负责执行单元测试用例。

下面说一下各个容器的作用和特点

(1)IgnoredBuilder,
	public Runner runnerForClass(Class<?> testClass) {
if (testClass.getAnnotation(Ignore.class) != null)
return new IgnoredClassRunner(testClass);
return null;
}

当在你的单元测试类前面加@Ignore的时候,这个容器就会被创建。这个容器不会执行单元测试方法。
这也就是当我们有些单元测试用例类跑不过时,加类上面加注解@Ignore,通过忽略通过的原因。

(2)AnnotatedBuilder
	@Override
public Runner runnerForClass(Class<?> testClass) throws Exception {
RunWith annotation= testClass.getAnnotation(RunWith.class);
if (annotation != null)
return buildRunner(annotation.value(), testClass);
return null;
}

在JUNIT已经提供了自己的容器,当在生产开发中,如果觉得JUNIT提供的容器已经不能满足需求时,可以自己创建个性化的容器。在类的声名加上注解RunWith,指定你自己创建容器。像在spring中,它提供了自己的单元测试容器。
请见Spring测试的基类AbstractJUnit4SpringContextTests,在它的类注解中加了RunWith,指定它的测试容器SpringJUnit4ClassRunner。
一般情况我们并不会用到这个容器。这里想说明的是JUNIT做为一个框架,它通过AnnotatedBuilder提供了可扩展的接口

(3)SuiteMethodBuilder 略

(4)JUnit3Builder
public class JUnit3Builder extends RunnerBuilder {
@Override
public Runner runnerForClass(Class<?> testClass) throws Throwable {
if (isPre4Test(testClass))
return new JUnit38ClassRunner(testClass);
return null;
}

boolean isPre4Test(Class<?> testClass) {
return junit.framework.TestCase.class.isAssignableFrom(testClass);
}
}

这是Junit的早期版本使用的容器,那时写单元测试类需要继承TestCase,现在我们不用再继承这个类了。为兼容老版本。当你的单元测试用例继承了TestCase这个容器就会被创建。isPre4Test方法判断你所写的测试用例类是否是TestCase的子类。记得好像3.8之后的版还是4.0之后的版就可以不用继承TestCase了。

(5)JUnit4Builder
	@Override
public Runner runnerForClass(Class<?> testClass) throws Throwable {
return new BlockJUnit4ClassRunner(testClass);
}

创建最新的Junit自带的测试容器。这个容器是我们现在最常用的,虽然我们并不了解它,但平常写的测试用例类都是在BlockJUnit4ClassRunner下运行的。由于版本原因,这里的BlockJUnit4ClassRunner是比较新容器。之前版本的容器是JUnit4ClassRunner,现在这个类已经打上@Deprecated注解,不再推荐使用。当然你也可以通过上面提到的RunWith来使用这个容器。

针对现在最常用BlockJUnit4ClassRunner,在下一个章节来看他的源码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值