如何实现Java测试的自定义断言

发表于:2014-7-03 11:57

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Tomek Kaczanowski    来源:51Testing软件测试网采编

  私有方法
  那么,我们究竟能做些什么呢?好吧,最显而易见的办法是将断言抽成一个私有方法:
private void assertThatRangeExists(List<Range> ranges, int rangeNb,
String start, String stop) throws ParseException {
assertEquals(ranges.get(rangeNb).getStart(), SDF.parse(start).getTime());
assertEquals(ranges.get(rangeNb).getEnd(), SDF.parse(stop).getTime());
}
@Test
public void shouldReturnHourlyRanges() throws ParseException {
// given
Date dateFrom = SDF.parse("2012-07-23 12:00");
Date dateTo = SDF.parse("2012-07-23 15:00");
// when
final List<Range> ranges = HourlyRange.getRanges(dateFrom, dateTo);
// then
assertEquals(ranges.size(), 3);
assertThatRangeExists(ranges, 0, "2012-07-23 12:00", "2012-07-23 13:00");
assertThatRangeExists(ranges, 1, "2012-07-23 13:00", "2012-07-23 14:00");
assertThatRangeExists(ranges, 2, "2012-07-23 14:00", "2012-07-23 15:00");
}
  这样是不是好些?我会说是的。减少了重复代码的数量,提高了可读性,这当然是件好事。
  这种方法的另一个优势是,我们现在可以更容易地改善验证失败时的错误信息。因为断言代码被抽到了一个方法中,所以我们可以改善断言,很容易地提供更可读的错误信息。
  为了更好地复用这些断言方法,可以将它们放到测试类的基类中。
  不过,我觉得我们也许能做得更好:使用私有方法也有缺点,随着测试代码的增长,很多测试方法都将使用这些私有方法,其缺点将更加明显:
  断言方法的命名很难清晰反映其校验的内容。
  随着需求的增长,这些方法将会趋向于接收更多的参数,以满足更复杂检查的要求。(assertThatRangeExists()现在有4个参数,已经太多了!)
  有时候,为了在多个测试中复用这些代码,会在这些方法中引入一些复杂逻辑(通常以布尔标志的形式校验它们,或在某些特殊的情况下,忽略它们)。
  从长远来看,所有使用私有断言方法编写的测试,意味着在可读性和可维护性方面将会遇到一些问题。我们来看一下另外一种没有这些缺点的解决方案。
  匹配器类库
  在我们继续之前,我们先来了解一些新工具。正如之前提到的,JUnit或者TestNG提供的断言缺少足够的灵活性。在Java世界,至少有两个开源类库能够满足我们的需求:AssertJ(FEST Fluent Assertions项目的一个分支)和 Hamcrest。我倾向于第一个,但这只是个人喜好。这两个看起来都非常强大,都能让你取得相似的效果。我更倾向于AssertJ的主要原因是它基于Fluent接口,而IDE能够完美支持该接口。
  集成AssertJ和JUnit或者TestNG非常简单。你只要增加所需的import,停止使用测试框架提供的默认断言方法,改用AssertJ提供的方法就可以了。
  AssertJ提供了一些现成的非常有用的断言。它们都使用相同的“模式”:先调用assertThat()方法,这是Assertions类的一个静态方法。该方法接收被测试对象作为参数,为更多的验证做好准备。之后是真正的断言方法,每一个都用于校验被测对象的各种属性。我们来看一些例子:
  assertThat(myDouble).isLessThanOrEqualTo(2.0d);
  assertThat(myListOfStrings).contains("a");
  assertThat("some text")
  .isNotEmpty()
  .startsWith("some")
  .hasLength(9);
  从这能看出,AssertJ提供了比JUnit和TestNG丰富得多的断言集合。就像最后一个assertThat("some text")例子显示的,你甚至可以将它们串在一起。还有一个非常方便的事情是,你的IDE能够根据被测对象的类型,自动为你提示可用的方法。举例来说,对于一个double值,当你输入“assertThat(myDouble).”,然后按下CTRL + SPACE(或者其它IDE提供的快捷键),IDE将为你显示可用的方法列表,例如isEqualTo(expectedDouble)、isNegative()或isGreaterThan(otherDouble),所有这些都可用于double值的校验。这的确是一个很酷的功能。
32/3<123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号