不会测验的开发不是好开发——鲁迅

【玩转Test】开篇-Android test 介绍

一直以来,关于如何写测验代码的相关内容资源都比较少,之前在优达学城看到了这部分的视频,但由于没有中文字幕,对有些小伙伴或许不太友好。因而我决议将其整理成c 1 s系列文章,那么就从认识 test 开始吧

本文内容来自 Udacity Advanced Android with Kotlin-LesP v Xson 10-5.1 Testing:Basics

结构

作为 Android 开发者咱们知道在 Android StudC ? 1 z q eio 的 And( M t Z B Sroid 视图中有三部分代码

  • app 的逻辑代码(main source set)
  • androidTest 代码
  • local te} % q @ _ X & .st 代码

test 代码知道一切的 main source set 中的0 V B % A代码,因而能够测验这些类。但是 app 代码不知道 test 中的代码,而且 androidTest 和 test 都不知道对方的存在。事实上,当你构建出 a5 } j 8 D _ j E .pk 并提交运用商场时,测验代码并没有包括在内

依靠引证

下面符号的依靠 运用了 test 的引证办法 testImplementationandroidTestImplementat& g 3ion

【玩转Test】开篇-Android test 介绍

留意:这些 test 代码不会打包到最终的 apk 文件} J ) X l ^ e

testImplementation 引证的 JUnit 依靠只能在 test source set 中运用,这种依靠规模的限制是 Gradle 完成的

简略总结下:

  • 三种 source setsmT Q I , 0 n a } 9aintestandroidTest
  • 测验代码能访问 app 代码
  • app 代码 不能 访问测验代码
  • 测验不会被打入到 Apk 中
  • 依靠规模包括:testImplementationandroidTestImplementation

运转榜首个 test

咱们打开 test source2 m r Y ^ set ,看到m J : & I z f @其中有一个 ExampleUnitTestI M 0 Z

【玩转Test】开篇-Android test 介绍

能够看到其内部只要一个 addition_isCorrect() 办法

F ^ H P ; 3 c两个要素使它成为一个 test:

  • 运用了 @Test 注解
  • 它存在于两个 tes2 V &t source set 之一

有了这两个要素,这个办法就能够Y D y b 独立的作为 test0 : A d & ~ 运转

本示例 test 测验的内容在第 15 行,它被称之为断语(assertion

断语是 test 的核心内容,它查看你的代码或许 app 行为是否符合你的预期

本示例中,断语查看 4 是否等g f J ,于 2 + 2

按照规则,您需求将你的 预期成果 传入到 expectedJ U D ? % Q 参数中,将 实际成果 传入到 actual 参数中

@Test 注解和断语语句都是 JUnit 下的

【玩转Test】开篇-Android test 介绍

关于 JUnit 的更详细的的信息,请移步 官方文档

让咱们开始运转一下这个 test,右击该办法,点击 Run

【玩转Test】开篇-Android test 介绍

紧接着,Run 窗口会呈现

【玩转Test】开篇-Android test 介绍

能够看到该窗口显示了 test 的信息,显示出 test 是否经过以及有多少 test 经过

下面咱们尝试一个 test 不经过的状况,咱们加入一个断语,如下所示

【玩转Test】开篇-Android test 介绍

{ J } W B p e次咱们点击 Run 窗口的绿色按钮来运转 test

【玩转Test】开篇-Android test 介绍

咱们能够看到,即使只要一个断语失利,整个 test 失利了

窗口指出了预期的成果) & @ F f为 5,而实际的成果为 4,而且下边符号处p / C M b = I过错发生在第 15 行,能够看到这的确是个 b[ % [ f w 2ug

处理好 bug ,咱们再次运转 test 。这次咱们运用一个不相同的办法

【玩转Test】开篇-Android test 介绍

下面介绍一些其他运转 test 的办法

能够右击类名挑选 Run 选项

【玩转Test】开篇-Android test 介绍

也能够在左侧视图中右击 test source set 挑选 Run 按钮,该办法会运转= F x / S一切 test。在顶部能够切换要运转的 test ,点击绿色按钮能够运转t , q | } d。也可切换回U T n app

【玩转Test】开篇-Android test 介绍

androidTest VS test

下面咱们来比照一下 androidTe4 2 n e X usttest

test androidTest
Local Tests Instrumented Tests
Local machineb d X X ? JVM Real or e ` J 3 6 v 7 l 4mulate[ % xd deviceT U } {s
Faster Slq O Q &ower

咱们来运转一个 androidTest,能够看到启动了模拟器

【玩转Test】开篇-Android test 介绍

写一个 test

首要咱们针对一个功用来创建 test,如图所示,存在一个 getForkAndOriginRepoStats() 办法用于获取 fork 库房和原始库房的数据E u J Z A / d )并返回 StatsResult,其中 StatsResult 榜首个参数为 fork 项目的~ V d百分比,第二个参数为原始项目的百分比。咱们调用 Generate ,选中 test 选项,在弹出框中挑选 JUnit4,点击 OK 并挑选存放在 local test 中。这样咱们就创建了一个 test

【玩转Test】开篇-Android test 介绍

接下来咱们编写 test 。能够看到自动创建出的 test 途径与 app code 中的代码途径的包名是对应的。咱们先测验项目列表只要一个 item,R 4 R R [而且没有 fork ,然后核算 fork 项目的百分比和原始项目的百分比。理论上讲,fork 项目的百U O x B & X B [ M分比为b ( 3 ] d C @ q ^ 0 ,而原始项目的百分比为 100%,代码如下图所示,咱们编写结束后点击运转

【玩转Test】开篇-Android test 介绍

能够看到测验经过

这是一个正常流程,咱们还需求测验异常的流程,比方 repos 为 emp: P G T ! % t / mty list 或许 repos 变量本身为 null

【玩转Test】开篇-Android test 介绍

能够看到咱们的代码中没有针对 list 为 empty 或 null 做判别,所以导致了空指针,之后咱们修正代码后即可经过测验

事实上,咱们上面的编码流程叫做 Test Driven Development(TDD) 有关 TDD 的更多信息,能够移步W / m D # m Test-Driven Development on Android with the A* p $ a j & Z ^ndroid Testing Support Library (Google I/O ’17)

让你的 test 更具可读性

与写一般) ( K代码相同,您需求让您的 test 代码更具可读性,能够从三个方向入手

  • 优异的命名
  • Given/When/Then
  • 借助断语库

优异的命名

首要咱们来谈谈命名,咱们知道 test 办法运用 @Test 注解符号,理论上办法名能够随意命名,但随意的命名会导致可读性的下降,因而需求一些特定的命名标准

测验模块C 9 I_ 动作或输入_ 成果状况

例如上面的例} – n 3 Q 5 g子咱们的命名为:getForkAndOriginRepoStats_noForked_returnHundredZero

榜首部分显示咱们要测验的是 getForkAndOriginRepoStats() 办法,第二部分代表咱们需求的是没有 for2 4 0 [k 库r ( 2 O 2 x房的数据源,第三部分是成果的状况,0%

Given/When/Then

说完了命名咱们来谈谈 Given/When/Then

测验的根本结构是 Given X,When Y,Then Z

还是上面的例子

  • Given 为你的测验逻辑供给数据源
  • When 是你的实际操 U = d A K
  • Then 查看 test 是否经过
【玩转Test】开篇-Android test 介绍

借助断语库

上面示例最终的断语代码让人看着很别扭,咱们能够借助断语库来提高这部分的可读性

// 之前
assertEquals(result.forkPercent, 0f)
// 之后
assk b - t b # ;ertThat(result.forkPercent, `is`(0f))

下面的语句就W t 像人类的一句话,翻译下来就是 断语 forkPercent 是 0f

这样的写法需求引进一个库 Hamcrest

testImplementation , % f  3 E"org.hc S E f ] )amcrest:hamcrest-all:1.3"
【玩转Test】开篇-Android test 介绍

留意:由于 is 是 kotlin 中的关键字,因而运用 `is` 来转义

常用的断语库

  • Hamcrest
  • Truth Library

测验规模

测验规模指一个 test 测验多少代码

例如自动化测验根据测验规模能够分为

  • Unit Tesc Y Q @ Xts(单元测验)
  • InP } & $ X / ?tegration Tests(拼装测验% 5 ! V d } x : z
  • End to end Tests(端到端测验)

您的测U R 9 | = #验战略需求掩盖到一切的类型

Unit Tests

上面的示例咱们已经写过了 Unit TeS G 2sts

  • 规模是单个o _ j 3 G ] r办法或类
  • 帮助查明失利原因
  • 应该运转的很快,通常是本地测验
  • 低保真度

他们的规模是单个的办法或类

假如 Unit Tests 失利了,您知道您的代码在哪里出了问题。由于它聚集于很小一段代码

Unit Tests 也意味着能够快速运转,由于您频频地修正代码会使得它会频频的运转,因而需求速度Q 5 I ) l 2 dUnit Tests 通常是本地测验

它们有较低的保真度,由于实际世界您的 app 要执行许多代码而不仅仅是一个办法或许类

Unit Tests 就像查看一个y & 7 H 9链条的每个环节是否能够正常运转

【玩转Test】开篇-Android test 介绍

但它不查看这些环节组合在一起是否能够运转,为此您需求 I$ 0 # T =ntegration Tests

Integration Tests

【玩转Test】开篇-Android test 介绍

I^ 0 D # C L ] Wntegration Tests 具有更大的规模

  • 规模是几个类或单个功用
  • 保证几个– f ? $ _ ` 类共同运转
  • 能够运用本地测验或机器测验

就像 Integration 这个词相同: ] O EIntegration Tests 整合一些类保证他们组合起来的表现符合预期

构建 Integration Tests 的办法是让他们测验单个功用,就像获取指定用户的 Github 库房

Unit Tests 相比,Integration Tests 有着更大的规模,但他们仍运转的很快而且有着很好的保真度

根据具体状况来判别运用本地z G n y R y D测验还是机器测验,例如假如您写的 Integration Tests 触及到了 UI 组件,那么您需求运用真机来测验了

End to end Tests

第三种类型是 End to end Tests,该测验将一些列功用组合起来一起运转

【玩转Test】开篇-Android test 介绍
  • 规模是 app 的大部分
  • 高保真度
  • 将 app 作为全体来测验
  • 接近真实地运用,应该运用设备测验V L { t ~ v

End to end Tests 测验 app 的大部分,它非常接近真实地运用,因而速度上会比较慢

它有着最高的保真度并保证您的运用k p A Q I = +作为一个全体运# u Q . . 0

A ( N些测验应该运用设_ 9 k备测验

测验比重

引荐的测验份额是 70% 的单元测验,20% 的d v q拼装测验,以及10% 的端到端测验

【玩转Test】开篇-Android test 介绍

您能否轻松地在各个部分测验您的 app 取决于您的 app 运用的结构

例如,您的运用将一切逻辑都放置在一个 activity 的大的办法中,您或许能够写出端到端测验,但单元测验和拼装测验则写不出来

【玩转Test】开篇-Android test 介绍

一个更好的架构应该B O – T + ; ?将运用的逻辑拆分为多个办法和类,这允许每部分能够独立的测验

【玩转Test】开篇-Android test 介绍

对于单元测验,您能够测验 ViewModelRepository 以及 DAO

【玩转Test】开篇-Android test 介绍

对于拼装测R r %验,您能够组合测验 fragmentViewModel ,或许您能够测验整个数据库代码

【玩转Test】开篇-Android test 介绍

端到端测验会测验整个运用

【玩转Test】开篇-Android test 介绍

关于@ M c E q测验的原理,可移步 官方文档

test 的 codelab

关于我

我是 FlU 1 m R oy_with24

  • 掘金
  • 简书
  • Github