其中一个比较有趣的用JUnit Rule实现的功能,是实现类似于BDD测试框架的命名方式。做单元测试的时候,你经常需要为同一个方法写好几个测试方法,每个测试方法测试不同的点。为了让命名更具可读性,我们往往会把名字写的很长,在这种情况下,如果用驼峰命名的话,需要不断切换大小写,写起来麻烦,可读性也不高。如果用下划线的话,写起来也很麻烦。如果你使用过BDD的一些框架(比如RSpec、Cucumber、Jasmine等),你会异常怀念那种“命名”方式。如果你没用过的话,那种“命名”方式大概是这样的:
  describe Hash do
  # 一下是一个测试方法,it后面的字符串是这个测试方法的“命名”
  it "hashes the correct information in a key" do
  expect(hash[:hello]).to eq('world')
  end
  end
  这里的关键是,当测试方法失败的时候,这个字符串是要能被加到错误信息里面的。我们做了个JUnit Rule来达到这个效果。做法是结合一个自定义的annotation,这个annotation接收一个String,来描述这个测试方法的测试目的。在Rule里面将这个annotation读出来,如果测试没通过的话,把这个描述性的String加到输出的error message里面。这样在批量运行的时候,一看知道没通过的测试是测什么东西的。而测试方法的命名则可以比较随意。
  达到的效果如下:

  如果运行失败,得到如下的结果

  关于JUnit Rule的使用,大家可以自行google一下,也不难。
  7. 善于利用AndroidStudio来加快你写测试的速度
  AndroidStudio有很多feature可以帮助我们更快的写代码,比如code generation和live template。这点对于写正式代码也适用,不过对于写测试代码来说,效果更为突出。因为大部分测试代码的结构、风格都是类似的,在这里live template能起非常大的作用。此外,如果你先写测试,可以直接写一些还不存在的Class或method,然后alt+enter让AndroidStudio自动帮你生成。
  8. 不要求完美
  刚开始的时候,不用追求测试代码的质量,也不用追求完美,如果有些地方不好写测试,可以先放放,以后再来补,有部分测试总比没有测试好。Martin Fowler说过
  Imperfect tests, run frequently, are much better than perfect tests that are never written at all.
  然而等你熟悉写测试的方法以后,强烈建议先写测试!因为如果你先写了正式代码,那你对这写代码是如何work的已经有一个印象了,因此你往往会写出能顺利通过的测试,而忽略一些会让测试不通过的情况。如果先写测试,则能考虑得更全面。
  9. 未来的打算
  使用Groovy和RoboSpock或者是Kotlin和Spek,真正实现BDD,这是很可能的事情,只是目前我们这边还没太多那方面的实践,因此不说太多了。以后有一定实践了,到时候可以再更大家交流。