扩展 JUnit 4,使用定制的 Runner

JUnit 的测试用例总是由 Runner 去执行,JUnit 提供了 @RunWith 这个测试类的 Annotation, 可来指定自定义的 Runner。如果未指定特别的  Runner,那么会采用默认的 Runner,可能不同的环境,如 Eclipse,控制台下会有不同的默认 Runner。

如果不清楚 Runner 是什么,那么可能见过 @RunWith(SpringJUnit4ClassRunner.class) 这个东西,它有助你加载 Spring 的配置文件,及与 Spring 相关的事物。

那么自定义的 Runner 有什么用呢?它可以截获到 @BeforeClass, @AfterClass, @Before, @After 这些事件,也就是能在测试类开始和结束执行前后,每个测试方法的执行前后处理点事情。

比如说从外部读取内容进行初始化测试数据,而且 JUnit 本身就提供了 @RunWith(Parameterized.class)  这个参数化 Runner,用了为带参数测试方法循环填充数据进行测试。JUnit 的参数化测试比 C# 还是要笨拙一些,C# 直接用方法注解一行行设置参数,我想 JUnit 稍加定制的话也行的。

现在用个例子来说明定制化 Runner  的表现功力,需继承自 BlockJUnit4ClassRunner, 这又是继承自 ParentRunner。可自定义那些 with 开头的方法来截获相应的事件,如:

来自  ParentRunner  的 withBeforeClasses, withAfterClasses
和定义的 BlockJUnit4ClassRunner 中的  withBefores, withAfters, withPotentialTimeout

等等,总之祖先类中的  protected 方法一般就是给大家开的口,看例子:

上面的  junitStatement.evaluate() 才是真正去执行相应的用 @Before, @After, @BeforeClass, @AfterClass 和 @Test 标的方法,所以可以在执行真正方法前面植入点什么。

看测试类:

看执行效果吧:

Before Class: cc.unmi.MyTest
execute beforeClass
After method: should_return_something_if_age_equals_18
Before before method: should_return_something_if_age_equals_18
execute before
execute should_return_something_if_age_equals_18
After before method: should_return_something_if_age_equals_18
execute after
execute afterClass
After Class: cc.unmi.MyTest

由于给出了的执行结果,所以就不多解释了。

应用场景探讨:因为在 “拦截” 方法中可以感知道当前执行类和方法,所以可以在 withBeforeXxx 时初始化测试数据,比如可以加入自定义的注解,根据注解,继续用反射的方式对类、实例变量进行初始化,或某些清理工作。

再学习下 JUnit 的 @RunWith(Parameterized.class) 参数化测试。除此之外,还有 @ClassRule 和  @Rule 也有异曲同功之妙,见 JUnit扩展方式(一)-使用Rule对JUnit进行扩展(JUnit4.10)

参考: 1. JUnit扩展方式(二)-使用Runner对JUnit进行扩展(基础)
          2.  JUnit中的测试套件和参数化测试
          3. 使用 Feed4JUnit 进行数据与代码分离的 Java 单元测试
          4. 使用RunWith注解改变JUnit的默认执行类,并实现自已的Listener
          5. JUnit扩展方式(一)-使用Rule对JUnit进行扩展(JUnit4.10)

类别: Java/JEE. 标签: , . 阅读(2,548). 订阅评论. TrackBack.

Leave a Reply

Be the First to Comment!

avatar