做Android开发,实在有太多的开源库和框架供开发者选用,总是让人无所适从到底哪个才是真正合适的。但是在自动化单元测试这一块,库的选择反而少了许多。可能是这些库实在太优秀了,也可能自动化测试的受重视程度相对较低所以没有太多人投入研发之中。
但是,自动化测试特别是单元测试(Unit Test)对于提高代码质量有很大的帮助。本文就来介绍一些Android中常用的单元测试库。
Junit
Junit是最主流的Java自动化则是框架,目前发展到Junit4。通过各种Java注解(Annotation)来标识测试的基本信息。
每个测试经历几个流程:设置,执行,验证。上手简单,运行快速,结果直观。API设计也很简洁,很容易扩展。
Mockito
单元测试最重要是减少测试对象的依赖,专注在该测试对象上。Mockito框架能很好的帮助我们完成这一目标,它在运行时将部分类在二进制层面替换掉,如此测试就不用依赖在实际代码上。
另外,单元测试中的断言验证(assertion)一般都是基于对象的状态(state),而Mockito提供了基于行为(behavior)的验证方式。
Robolectric
在Android的代码则很大程度依赖于Android的系统库,比如Context,View等等。其他几个库都是基于Java开发出来的,在单元测试中无法调用到Android系统的代码。Roboletric的出现就很好的解决了这个问题,它为测试提供了Android的系统代码, 并且通过配置可以指定运行的API等级。
AssertJ
JUnit自带assert方法来验证测试结果,这些方法使用了Hamcrest的函数式API。AssertJ则更具面向对象设计,并且是流式接口(fluent interface),让代码书写更加流畅,在IDE中也有更好的补全功能。
另外AssertJ扩展性也非常强,对于各种常用的Java库都有相应的扩展来更好的适应单元测试,比如Guava。即使是Android也有开源扩展库。
其他可选库
Hamcrest
之前提到JUnit的assertion使用了Hamcrest的API。另外Android的Espresso测试也使用了Hamcrest。所以值得了解一下。不过友善度上还是AssertJ更好。
PowerMock
Mockito的缺点是不能模拟final的方法和类,对于通过new创建对象的语句也无能为力。PowerMock可以解决这些问题。
个人不建议使用PowerMock,不仅因为它的设置相对复杂,另外对于新写的代码,完全可以对代码进行修改使其更具可测试性,比如去掉final,或者使用依赖注入。
FEST-Assert
已经好多年没有更新了,AssertJ算是它的完全替代品。
进阶资源
写好测试代码有时候跟写好产品代码一样复杂。以上介绍的这些库大多解决的是比较通常的问题,但是实际代码往往有很多特定的实现和框架,此时就需要构建辅助测试的库来方便测试代码的实现。有时候为了可测试性,还需要对已经的代码进行重构,这又是一项软件工程。对于这方面,可以参阅一下资源。