Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android Unit Testing

Sylvain W
June 26, 2015
130

Android Unit Testing

Sylvain W

June 26, 2015
Tweet

Transcript

  1. 单元测试  单元测试其实是相对廉价而简单的技术,但它能让你更高效地写出 质量更好的代码。  说到测试,大凡组织和个人都会满怀雄心壮志,但是往往只是在项 目快要结束的时候才想起测试。而那时的进度压力⼀定非常紧迫, 所以结果往往只是浅尝辄止或者干脆就不测试了,这样就起不到预 防缺陷的意义。 

    当基本的底层代码不再可靠时,那么必需的改动就无法只局限在底 层,虽然你可以修正底层的问题,但是这对底层代码的修改必然会 影响到高层代码,于是高层代码也连带地需要修改;以此递推,就 很可能会动到更高层的代码。于是,⼀个对底层代码的修正,可能 会导致对几乎所有代码的⼀连串改动,从而使修改越来越多,也越 来越复杂。项目中存在的风险越来越高,导致整个项目的失败的可 能性也越来越大。  简而言之,在有些时候,使用单元测试本身就能决定你的项目的成 败。
  2. 单元测试:收益  单元测试的目标是隔离程序部件并证明这些单个部件是正确的。⼀ 个单元测试提供了代码片断需要满足的严密的书面规约。因此,单 元测试带来了⼀些益处。 单元测试在软件开发过程的早期就能发现 问题。 1. 适应变更:单元测试允许程序员在未来重构代码,并且确保模块依然工作正确(复 合测试)。这个过程就是为所有函数和方法编写单元测试,⼀旦变更导致错误发生,

    借助于单元测试可以快速定位并修复错误。 2. 简化集成:单元测试消除程序单元的不可靠,采用自底向上的测试路径。通过先测 试程序部件再测试部件组装,使集成测试变得更加简单。 3. 文档记录:单元测试提供了系统的⼀种文档记录。借助于查看单元测试提供的功能 和单元测试中如何使用程序单元,开发人员可以直观的理解程序单元的基础API。
  3. 单元测试:测试范畴  它的行为和我期望的⼀致吗? 这是单元测试最根本的目的,我们就是用单元测试的代码来证明它所做的就是我们 所期望的。  它的行为⼀直和我期望的⼀致吗? 编写单元测试,如果只测试代码的⼀条正确路径,让它正确走⼀遍,并不算是真正 的完成。 软件开发是⼀个项复杂的工程,在测试某段代码的行为是否和你的期望⼀致时,你

    需要确认:在任何情况下,这段代码是否都和你的期望⼀致;譬如参数很可疑、硬 盘没有剩余空间、缓冲区溢出、网络掉线的时候。  我可以依赖单元测试吗? 不能依赖的代码是没有多大用处的。既然单元测试是用来保证代码的正确性,那么 单元测试也⼀定要值得依赖,并且清楚地知道这些代码的功能和约束。  单元测试说明我的意图了吗? 单元测试能够帮我们充分了解代码的用法,从效果上而言,单元测试就像是能执行 的文档,说明了在你用各种条件调用代码时,你所能期望这段代码完成的功能。
  4. JUnit单元测试  JUnit是⼀个开发源代码的Java测试框架,用于编写和运行可重复的 测试。它是用于单元测试框架体系xUnit的⼀个实例(用于java语 言)。主要用于白盒测试,回归测试。  JUnit特征: 1. 提供的API可以写出测试结果明确的可重用单元测试用例。 2.

    提供了测试结果的显示,而且还可以扩展。 3. 提供了单元测试用例成批运行的功能。 4. 超轻量级而且使用简单,没有商业性的欺骗和无用的向导。 5. 整个框架设计良好,易扩展。
  5. JUnit单元测试  JUnit框架组成: 1. 对测试目标进行测试的方法与过程集合,可称为测试用例(TestCase)。 2. 测试用例的集合,可容纳多个测试用例(TestCase),将其称作测试包(TestSuite)。 3. 测试结果的描述与记录(TestResult) 。

    4. 测试过程中的事件监听者(TestListener)。 5. 每⼀个测试方法所发生的与预期不⼀致状况的描述,称其测试失败元素(TestFailure)。 6. JUnit Framework中的出错异常(AssertionFailedError)。
  6. JUnit单元测试  Test接口:运行测试和收集测试结果 1. Test接口是单独测试用例(TestCase),聚合测试模式(TestSuite)及测试扩展 (TestDecorator)的共同接口。 2. 它的public int countTestCases()方法,用来统计测试时有多少个TestCase。

    3. 另外⼀个方法就是public void run(TestResult),TestResult是实例接受测试结果,run 方法执行本次测试。  TestCase抽象类:定义测试中固定方法 1. TestCase是Test接口的抽象实现,其构造函数TestCase(string name)根据输入的测试 名称name创建⼀个测试实例。 2. TestCase在创建时都要有⼀个名称,若测试失败了,便可识别出是哪个测试失败。 3. TestCase类中包含的setUp()、tearDown()方法。 4. setUp()方法集中初始化测试所需的所有变量和实例,并且在依次调用测试类中的每 个测试方法之前再次执行setUp()方法。 5. tearDown()方法则是在每个测试方法之后,释放测试程序方法中引用的变量和实例。 6. 编写测试用例时,只需继承TestCase,来完成run方法即可,然后JUnit获得测试用例, 执行它的run方法,把测试结果记录在TestResult之中。
  7. JUnit单元测试  Assert静态类:⼀系列断言方法的集合 Assert包含了⼀组静态的测试方法,用于期望值和实际值比对是否正确,即测试失败, Assert类就会抛出⼀个AssertionFailedError异常,JUnit测试框架将这种错误归入 Fails并加以记录,同时标志为未通过测试。 assertTrue 断言条件为真。 assertFalse 断言条件为假。

    assertEquals 断言两个对象相等。 assertNotNull 断言对象不为null。 assertNull 断言对象为null。 assertSame 断言两个引用指向同⼀个对象。 assertNotSame 断言两个引用指向不同的对象。 fail 让测试失败,并给出指定的信息。
  8. JUnit单元测试  TestResult结果类和其它类与接口 1. TestResult结果类集合了任意测试累加结果,通过TestResult实例传递个每个测试的 Run()方法。TestResult在执行TestCase时如果失败会异常抛出。 2. TestListener接口是个事件监听规约,可供TestRunner类使用。它通知listener的对象 相关事件,方法包括测试开始startTest(Test test),测试结束endTest(Test

    test),错误, 增加异常addError(Test test,Throwable t)和增加失败addFailure(Test test,AssertionFailedError t)。 3. TestFailure失败类是个“失败”状况的收集类,解释每次测试执行过程中出现的异 常情况。其toString()方法返回“失败”状况的简要描述。
  9. JUnit单元测试  JUnit测试框架目前主要有两种(JUnit3.8和JUnit4.x)。主要介绍 JUnit3.8的用法。  涉及到的包⼀般是 import junit.framework.*  在

    JUnit 3.8 中,测试类要继承TestCast类,而TestCast类又继承于 Assert类,测试方法需满足如下原则: 1. 修饰符设为 public 2. 返回类型 void 3. 没有方法参数 4. 方法名称必须以test开头 5. 测试类都继承于TestCase类  另外,使用过程中,测试类不能依赖于测试方法的执行顺序。
  10. Android测试  Android测试套件是基于JUnit的。  可以使用普通的JUnit测试(TestCase)来对不需要调用Andriod API的类进行测试。  或者使用Android's JUnit extensions来对Android组件进行测试。

     Android仪表(Instrumentation)能够获取⼀系列系统信息,包括gc 次数,分配对象和内存数量,释放对象和内存数量等。 1. ApplicationTestCase:主要用来测试Application,提供了对Application类生命周期方 法的基本支持,可以支持注入⼀些mock context对象等。测试时是要将app运行起来 的。 2. ActivityInstrumentationTestCase2:当前主流用于测试apps功能的测试类,大名鼎鼎 的robotium就是基于这个类来实现的。提供Activity生命周期支持,也需要将app运 行起来,同事可以通过instrumentation来获取系统信息。 3. ActivityUnitTestCase:为了单独测试Activity而存在,会以与系统底层关联性最小的 代价创建出来。不将activity运行起来,没有数据存储和交互依赖关系。
  11. Android测试:类的结构 java.lang.Object junit.framework.Assert junit.framework.TestCase android.test.InstrumentationTestCase android.test.AndroidTestCase android.test.ApplicationTestCase<T extends android.app.Application> android.test.LoaderTestCase

    android.test.ProviderTestCase2<T extends android.content.ContentPrivider> android.test.ServiceTestCase<T extends android.app.Service> android.test.ActivityTestCase android.test.ActivityInstrumentationTestCase2<T extends android.app.Activity> android.test.ProviderTestCase<T extends android.content.ContentProvider> android.test.ActivityUnitTestCase<T extends android.app.Activity> android.test.SingleLaunchActivityTestCase<T extends android.app.Activity>