Skip to main content

测试基础

测试的目标是为了保证质量,随着当今开发节奏的不断加快,仅仅依靠测试人员保证产品质量的日子也一去不返。在当今的开发中,内建质量开始越来越多的被提及,而自动化测试就是代码内建质量的关键一环。

也就是说,内建质量要求开发人员更多的去在开发的早期参与到测试活动当中。这也是测试驱动开发(TDD)所倡导的。

为了方便更好的理解自动化测试,这里将介绍一下有关测试的必要基础知识。


测试金字塔#

测试金字塔(如下图所示)说明了应用应如何包含三类测试(即小型、中型和大型测试):

  • 小型测试是指单元测试,用于验证应用的行为,一次验证一个类。
  • 中型测试是指集成测试,用于验证模块内堆栈级别之间的交互或相关模块之间的交互。
  • 大型测试是指端到端测试,用于验证跨越了应用的多个模块的用户操作流程。

测试金字塔

沿着金字塔逐级向上,从小型测试到大型测试,各类测试的保真度逐级提高,但维护和调试工作所需的执行时间和工作量也逐级增加。因此,您编写的单元测试应多于集成测试,集成测试应多于端到端测试。虽然各类测试的比例可能会因应用的用例不同而异,但我们通常建议各类测试所占比例如下:小型测试占 70%,中型测试占 20%,大型测试占 10%

测试迭代循环#

测试驱动的迭代开发关联的两个周期

上图表示了一个测试驱动开发的典型流程。

  • 迭代开发某项功能时,您可以先编写一个新测试,也可以将用例和断言添加到现有单元测试。测试最初会失败,因为该功能尚未实现。
  • 然后实现该功能,使测试通过。
  • 最后通过重构优化代码。

从图中可以看出,在开发中,程序特性相关的单元测试是UI测试的基础。但事实上,单元测试的重要性远不止如此,处于测试金字塔基座部分的单元测试是所有其他自动化测试的基础,在整个自动化测试的体系中具有最重要的地位。

测试驱动开发(TDD)#

测试驱动开发三原则#

  • 在编写不能通过的单元测试前。不可编写生产代码。
  • 只可编写刚好无法通过的单元测试,不能编译也算不通过。
  • 只可编写刚好足以通过当前失败测试的生产代码。

测试驱动开发的三原则简化来讲就是:

  • 测试先行
  • 小步快跑
  • 不过度设计

测试驱动开发三原则,只是测试驱动开发的一个最简的指导原则,实际上在完成了第三步之后,我们还要通过测试迭代循环中的重构环节来消除我们代码的坏味道,保持代码的整洁。测试代码可以保证我们重构过程的正确性。

优势#

测试驱动开发相较于传统的开发方式有很多优势:

  • 为重构与修改的正确性提供保障。
    测试驱动开发会让程序中的每一项功能都有测试来验证它的操作的正确性。这样如果我们在重构的过程中破坏了某些逻辑的正确性,就可以通过测试用例快速的知道出了什么问题。我们可以向程序中增加功能或者更改程序结构,而不用担心在这个过程中会破坏重要的东西。这样,我们可以更自由地对程序进行改进。
  • 利于设计出耦合度低、可测试的程序。
    先编写测试,我们就需要自己的程序是可测试的。为了成为易于调用和可测试的,程序必须和它的周边环境解耦。所以测试驱动开发的方式有助于我们编写出耦合度低的程序。

没有银弹#

测试驱动开发不是银弹。它并不是万能的,也有很多力所不及的地方。

  • TDD不能杜绝软件缺陷。
    如果你对业务本身的理解不够透彻,从而导致测试用例设计本身就有缺陷,那么即使你使用TDD,也无法得到正确的实现。
  • TDD不能节省开发投入,也很少能够节省开发周期。
    实际上,在很多时候,如果你是初次使用TDD的方式进行程序开发,很大概率上你会付出更多的时间。可能很简单的功能也需要从前完成一个复杂功能的时间才能搞定。TDD所能带给你的不是更快的开发速度,而是更快的响应变更的能力与持续改进优化的能力。

常用测试工具#

Android开发中常用的测试工具如下表所示: |名称|作用| |-|-| |Junit|单元测试框架。| |Mockito|模拟依赖的库,主要用于在单元测试中提供模拟依赖。| |PowerMock|模拟依赖的库,此库可以模拟 Mockito 无法模拟的一些依赖,如:final、static、private 方法的模拟。| |Robolectric|针对Android平台的单元测试框架,它可以在JVM环境下模拟Android系统组件,让对于依赖Android系统组件与应用上下文的测试可以不用打包即可运行,大大加快了测试执行的速度,是在Android平台下施行测试驱动开发的利器。| |Espresso|UI测试框架,一般用于单应用中的UI测试。| |UIAutomator|UI测试框架,一般用于跨应用的端到端测试。|


参考资料:
Android开发者 测试基础知识
测试驱动开发优缺点