Android单元测试调研

(一)Java JUnit Tests

1、JUnit

  • androidstudio创建工程自带
  • JUnit 在 Android 官网上出现的频率相当高,是 Android 单元测试的基础框架之一,后面提到的 mock 框架都相当于是在丰富这些基础框架的功能。
    要做单元测试的开发者们通常都会在 JUnit 和 TestNG 之间选择一个,个人感觉还是选 JUnit 好一些。(理由在 TestNG 的介绍中)
  • 这种测试运行在本地开发环境的Java虚拟机上,不需要连接Android设备或者模拟器,因此无法获得Android相关的API,所以只能测试只使用Java API的一些功能。
    测试类代码编写也很简单,主要通过一些注解来标示,同时可以通过assertXXXX来断言结果

2、TestNG

  • TestNG 对 JUnit 的改进主要在两个方面:
  1. 在 JUnit 中,同一个测试类中的不同测试方法是相互独立的,也就是说,每个测试方法开始前都会执行一次测试类的构造方法,这就让测试方法之间共享某些状态变得不可能
  2. 后来 JUnit 对问题1给出了解决方案—— TestSetup,但是它必须通过静态方法去使用(JUnit 的 TestSetup 因为年代久远)
  • 理论上单元测试case之间应该隔离的 不应该有依赖关系
  • 设计 JUnit 侧重点分析代码单元,而 TestNG 的预期用途则针对高级测试。

3、Spock

      是测试领域的新成员

  • 测试代码使用Groovy语言编写,而被测代码可以由Java编写。
  • 内置mock框架以减少引入第三方框架。
  • 为创建测试代码预定义了行为驱动块(given:、when:、then:、expect:等)。

4、Mock框架

Mock 方法是单元测试中常见的一种技术,它的主要作用是模拟一些在应用中不容易构造或者比较复杂的对象,从而把测试与测试边界以外的对象隔离开。

(1)EasyMock

EasyMock 是早期比较流行的MocK测试框架。它提供对接口的模拟,能够通过录制、回放、检查三步来完成大体的测试过程,可以验证方法的调用种类、次数、顺序,可以令 Mock 对象返回指定的值或抛出指定异常。通过 EasyMock,我们可以方便的构造 Mock 对象从而使单元测试顺利进行。

(2)Mockito

  • Mockito 的优势正如它官网说的:
  1. 测试代码和验证提示的良好可读性
  2. 良好的社区支持
  3. Java 世界中排名能到达前十的明星框架
  4. Features And Motivations
  • 但劣势也同样明显,其实不应该叫做“劣势”,而应该说是因为实现方式所带来的“限制”:What are the limitations of Mockito
  • 不过这些限制也因为 PowerMock 的出现而被化解,所以搭配上 PowerMock 之后,Java 单元测试这边几乎所向披靡。

(3)PowerMock

  • 它绕开了 CGLib,直接修改类的字节码,以实现 mock 某个类的目的。这种风骚的操作让 PowerMock 能够做到上面提到的框架做不到的事情:修改静态或私有方法等等。
  •  然而,它把自己定位为高层次框架的插件,所以用它的时候就不可避免要带上其他的框架(在 gradle 里引入 PowerMock 的时候会自动引入相关框架的依赖),比较沉重。
  • 如果已经使用了 Mockito 之流,那在后期引入 PowerMock 的时候必须让二者的版本相对应,或者抛弃原来的 Mockito,直接使用 PowerMock 依赖的版本。

(4)JMockit

  • Jmockit是一个功能很强大的框架,可以mock静态方法、final类、抽象类、接口、构造函数等,但编程语言不够简洁。
     

Mock小结:目前安卓最常用的Mock有两个,Mockito和JMockit。两者的区别是:

前者不能mock static method和final class、final method,后者可以

但是JMockit跟robolectric的结合也有一些bug,同时使用姿势跟Mockito有较大的不同,JMockit需要在执行前记录期望行为(expectations),显得很繁琐。

而Mockito通过在执行后校验哪些函数已经被调用,消除了对期望行为(expectations)的需要,API非常简洁,比较成熟稳定,兼容性也比较好。Mockito在github上面有2000多个mark,而JMockit只有100多个。

所以可以采用Mockito的框架,在亟需mock static method final class时候引入PowerMock即可

(二)Android Unit Tests

1、Robolectric

  • 按照文档中的描述,Shadow class 是用来修改和扩充 Android OS 下的类的行为的,除了可以 shadow 构造方法外,它和 Mockito 的 mock 没有太大区别,所以它并不能作为 Mockito 的扩充来使用。
  • 官网的介绍中也提及了 Mockito,按照它的说法,我们完全可以用 Mockito 来实现 Robolectric 的功能,只不过要我们自己将 Android SDK 和一些 native 方法一个个 mock 掉而已。这部分工作正是 Robolectric 的价值所在。
  • Robolectric运行在jvm上,但是框架本身引入了android依赖库,所以可以做android单元测试,运行速度比运行在真机or模拟器快。

  • 但Robolectric也有局限性,例如不支持加载so(可以mock解决),测试代码也有点别扭。当然,robolectric可以配合junit、mockito使用。

  • Robolectric仅支持API21及以下,并且不支持jni库。因此,如果你的代码依赖了API21以上接口或者jni接口,robolectric也无能为力。

2、Espresso

  • Espresso是Google官方推出的Instrumentation UI测试框架,在API支持方面有着天然的优势,在推出后很大程度上将替代Robotium。

  • Espresso 测试框架提供了一组 API 来构建 UI 测试,适合应用中的功能性 UI 测试,用于测试应用中的用户流。利用这些 API,您可以编写简洁、运行可靠的自动化 UI 测试。Espresso 非常适合编写白盒自动化测试,其中测试代码将利用所测试应用的实现代码详情。

  • Espresso 测试框架的主要功能包括:
    灵活的 API,用于目标应用中的视图和适配器匹配。
    一组丰富的操作 API,用于自动化 UI 交互。
    UI 线程同步,用于提升测试可靠性。

  • 要求 Android 2.2(API 级别 8)或更高版本。不可跨进程等(跨进程可使用Uiautomator)

  • Espresso依赖了hamcrest
    esspresso中的matcher都属于自定义的hamcrest matcher,hamcrest matcher还被用于Mockito、Junit等框架中。例如:onView方法使用一个matcher在视图层中获得唯一一个匹配的视图对象。

3、UI Automator

  • 适合跨系统和已安装应用的跨应用功能性 UI 测试
  • UI Automator 测试框架提供了一组 API 来构建 UI 测试,用于在用户应用和系统应用中执行交互。利用 UI Automator API,可以执行在测试设备中打开“设置”菜单或应用启动器等操作。UI Automator 测试框架非常适合编写黑盒自动化测试,其中的测试代码不依赖于目标应用的内部实现详情。
  • UI Automator 测试框架的主要功能包括:

          用于检查布局层次结构的查看器。
          在目标设备上检索状态信息并执行操作的 API。
          支持跨应用 UI 测试的 API。
          要求 Android 4.3(API 级别 18)或更高版本。

4、Android JUnit Runner

      AndroidJUnitRunner,Google官方的android单元测试框架之一,适用于 Android 且与 JUnit 4 兼容的测试运行器!测试运行器可以将测试软件包和要测试的应用加载到设备、运行测试并报告测试结果。

  • 是一个测试运行器,用于运行Junit3和Junit4的Android测试包
  • 替换Instrumentation Test Runner(一个比较旧的测试运行器)
  • 支持Instrumentation Test Runner所有特性,但又进行了扩展
  • 保持了所有Instrumentation Test Runner的命令格式
  • 也需要连接真机或模拟器

Guess you like

Origin blog.csdn.net/cpcpcp123/article/details/121655163