JUnit 5 Alpha版本简化了单元测试

发表于:2016-04-06来源:infoq作者:Abraham Marín Pérez点击数: 标签:单元测试
JUnit是流行的Java单元测试框架,近日JUnit Lambda团队宣布发布新的主要版本——JUnit 5 alpha版本。通过一个成功的众筹活动允许全职开发人员工作在该项目上,JUnit 5的主要变化集中在去除了

  JUnit是流行的Java单元测试框架,近日JUnit Lambda团队宣布发布新的主要版本——JUnit 5 alpha版本。通过一个成功的众筹活动允许全职开发人员工作在该项目上,JUnit 5的主要变化集中在去除了JUnit 4带给开发人员的普遍问题,同时修改了框架以便于将来的变更。与构建工具和集成开发环境的整合仍需要一些额外的工作。

  JUnit 5已经适应了开发人员每天编写单元测试的方式,开发人员对此非常感激。例如,尽管JUnit FAQ传统上反对在一个单元测试中放多个断言,但是一些轶事证据表明,开发人员倾向于这么做。一个测试中包括多个断言的风险是一旦其中一个失败,测试执行就会停止,不会执行其他的断言。因此,JUnit 5 支持分组断言(grouped assertions),所有的断言都会被执行,即使其中一个或多个断言失败:

  @Test

  void groupedAssertions() {

  assertAll("address",

  () -> assertEquals("John", address.getFirstName()),

  () -> assertEquals("User", address.getLastName())

  );

  }

  来自JUnit 5用户指南的示例代码。

  让人不满意的另一个常见原因是对测试异常的支持,因为JUnit 4中提供的几种方式都不能满足开发人员的需求。人们可以用@Test注解中的”expected“选项表示期望抛出的异常类型;但是,对于更复杂的断言,这是不够灵活的,比如在抛出的异常中检查异常信息。在这种情况下,开发人员可以用@Rule 和 ExpectedException,这确实支持使用匹配器来检查异常信息;然而,即使是ExpectedException 也不足以进一步测试像自定义字段或方法的异常对象,或在抛出异常的方法后执行额外的断言。

  为了解决这个问题,JUnit 5提供了一个新的断言,expectthrows,不仅可以检查一个特定方法抛出的预期异常,同时将异常对象作为一个结果返回,允许进一步测试。

  @Test

  void exceptionTesting() {

  Throwable exception = expectThrows(IllegalArgumentException.class,

  () -> { throw new IllegalArgumentException("a message"); }

  );

  assertEquals("a message", exception.getMessage());

  }

  来自JUnit 5用户指南的示例代码。

  扩展性也是新版本关注的一个方面。JUnit 4主要的扩展机制是@RunWith。但是,@RunWith在任何给定的测试类上只能使用一次,这意味着开发人员不能同时使用,例如,Parameterized 在同样的测试中应用不同的数据以及MockitoJUnitRunner自动设置mocks。在JUnit 5 @RunWith已经被@ExtendWith取代,这是一个新的扩展机制,支持多个实例被使用。

  为了让开发人员逐步升级到新版本,JUnit 5所有的类已经迁移到新的包,许多注解已经重命名。此外,JUnit Lambda团队为JUnit 4创建了一个JUnit 5 Runner ,允许使用JUnit 5所有特性的同时仍然以JUnit 4为主要的测试框架。这使得JUnit 4和JUnit 5有可能在同一个项目中同时使用,使过渡变得更容易。

  被关注的问题还有,通过语义化的版本号命名(semantic versioning)和加注解的API,使得未来的变更更加方便,甚至包括那些向后不兼容的变更。从JUnit 5开始,测试框架中每一个公共类和接口都将标有下列值之一:

  Internal:不适合在框架之外使用,随时可能被删除,并且可能不会事先通知。

  Deprecated:不应使用的,在下一个小版本可能会去掉。

  Experimental:用来收集对新概念的反馈,它可能被改进,也可能在没有事先通知的情况下被删除。

  Maintained:从当前版本到至少下一个小版本没有向后不兼容的更改,如果计划删除,它首先会被修改为Deprecated。

  Stable:在目前的主要版本没有向后不兼容的更改。

  在上一个主要版本发布十年之后,JUnit似乎赶上了时代的步伐。虽然与构建工具和集成开发环境的整合还需要一些工作,但是为Maven和Gradle 提供的插件看起来是相当先进的,这似乎表明,在可预见的未来JUnit将继续是主要的Java测试框架。

原文转自:http://www.infoq.com/cn/news/2016/03/junit5-alpha