自定义测试规则

来源:互联网 发布:mac魔兽争霸3不能联网 编辑:程序博客网 时间:2024/05/10 13:02


在junit4X之前的版本,测试的API都是基于继承junit.framework.TestCase的测试类,所以扩展junit要覆盖某些继承行为。junit4X系列之后junit采用注解的方式,所以我们来扩展junit的时候也就多了一种选择。
扩展内置的junit行为的主要相关概念是运行器和规则。尽管我们不大会深入自定义插件,但是我们还是应该意识到哪些插件是内置的,以及如何开始编写自定义插件。
从上一篇博客中,我们也看出来了,实现自定义运行器不是一件小事,所有出于这个原因,我们更倾向于自定义规则。所以这篇博客的内容主要集中于junit的规则是如何工作的,以及那些规则是我们可以开箱即用的。


规则是最近才加到junit中的,它能操纵测试的执行。比如,规则的实现能跳过整个执行,或在测试运行前后来执行一些setup或teardown。规则是应用到类这以及,你可以对一个雷应用多条规则。
多条规则的情况下,每次会应用一条。注意的是:junit并不保证应用规则的顺序。


junit观察一个测试类时,它会为运行每个找到的测试建立一个执行计划。规则,即org.junit.rules.MethodRule的实现,基本上会封装或代替当前的执行计划。
OK,现在让我们来看一看那些是内置的规则。
junit没有将规则API作为一个扩展点来提供给用户,大量基础的junit都是用同样的API实现的,包括整个测试类的全局超时,处理期望异常的复杂方式,以及临时文件系统资源的管理。

  • 1,配置全局超时
当然,我们可以使用@Test(timeout=X)来为测试方法设置超时,在这里我们使用规则API来一次性的为类中的所有的测试定义超时。代码如下:
package org.linkinpark.junit.testjunit;import org.junit.Assert;import org.junit.Rule;import org.junit.Test;import org.junit.rules.Timeout;/** * @创建作者: LinkinPark * @创建时间: 2016年2月16日 * @功能描述: 全局超时的一个例子 */public class GlobalTimeoutTest{@Rulepublic Timeout globalTimeout = Timeout.millis(20);@Testpublic void test(){Assert.assertEquals("1", "1");}@Testpublic void run1() throws InterruptedException{Thread.sleep(100);}@Testpublic void infiniteLoop(){while (true){}}}
关于上面的代码,我这里解释一下如何配置全局超时:

1,定义一个MethodRule类型的属性

2,该属性用@Rule注解修饰

3,属性的名字倒是无所谓,一般按照实际的意义来命名就好了。

上面的代码中我自己写了3个测试,其中有2个测试的执行时间都超出了20秒,所以2个测试失败。junit控制台输出如下:




  • 2,预期的异常
当然我们已经知道了,使用@Test注解接受expected=X属性,用于在没有抛出指定类型的异常的时使得测试失败。

当然我们也可以使用try和catch来捕获异常,然后使用hamcrest匹配异常信息。

这里在介绍一种相对比较复杂的规则,就是使用expectedException规则来测试异常的信息,根因。代码如下:

package org.linkinpark.junit.testjunit;import org.junit.Rule;import org.junit.Test;import org.junit.rules.ExpectedException;/** * @创建作者: LinkinPark * @创建时间: 2016年2月16日 * @功能描述: expectedException规则的一个例子 */public class SimpleExpectedExceptionTest{@Rulepublic ExpectedException thrown = ExpectedException.none();@Testpublic void throwsNothing(){// no exception expected, none thrown: passes.}/** * @创建时间: 2016年2月16日 * @相关参数: * @功能描述: 单纯的测试抛出异常的类型 */@Testpublic void throwsExceptionWithSpecificType(){thrown.expect(NullPointerException.class);throw new NullPointerException();}/** * @创建时间: 2016年2月16日 * @相关参数: * @功能描述: 测试抛出的异常类型+异常信息 */@Testpublic void throwsExceptionWithCorrectMessage(){thrown.expect(RuntimeException.class);thrown.expectMessage("LinkinPark");throw new RuntimeException("LinkinPark。。。");}}

3,临时文件夹

大多数单元测试应对远离文件系统,但时不时会要编写一个自动的,可重复的,与文件系统中的文件打交道的测试。这就是最后一个规则的用武之地。
TemporaryFolder是个简单的工具,利用它我们可以容易的在测试中创建临时文件和文件夹,并令其在测试运行之后自动消失。

package org.linkinpark.junit.testjunit;import java.io.File;import java.io.IOException;import org.junit.Assert;import org.junit.Rule;import org.junit.Test;import org.junit.rules.TemporaryFolder;/** * @创建作者: LinkinPark * @创建时间: 2016年2月16日 * @功能描述: 创建临时文件夹的一个例子 */public class HasTempFolder{@Rulepublic TemporaryFolder folder = new TemporaryFolder();@Testpublic void testUsingTempFolder() throws IOException{// 创建临时文件File createdFile = folder.newFile("myfile.txt");// 创建临时文件夹File createdFolder = folder.newFolder("subfolder");System.out.println(createdFile.getAbsolutePath());System.out.println(createdFolder.getPath());Assert.assertTrue(createdFile.exists());Assert.assertTrue(createdFolder.exists());}}


0 0