`
lxfgrace
  • 浏览: 74369 次
  • 性别: Icon_minigender_2
  • 来自: 重庆
社区版块
存档分类
最新评论

Instrumentation学习基础(一)

 
阅读更多
Android提供了一系列强大的测试工具,它针对Android的环境,扩展了业内标准的JUnit测试框架。尽管你可以使用JUnit测试Android工程,但Android工具允许你为应用程序的各个方面进行更为复杂的测试,包括单元层面及框架层面。

Android测试环境的主要特征有:

l   可以访问Android系统对象。

l   Instrumentation框架可以控制和测试应用程序。

l   Android系统常用对象的模拟版本。

l   运行单个test或test suite的工具,带或不带Instrumentation。

l   支持以Eclipse的ADT插件和命令行方式管理Test和Test工程。

这篇文章是对Android测试环境和测试方法的简要介绍,并假设你已经拥有一定的Android应用程序编程及JUnit测试的经验。

概要

Android测试环境的核心是一个Instrumentation框架,在这个框架下,你的测试应用程序可以精确控制应用程序。使用Instrumentation,你可以在主程序启动之前,创建模拟的系统对象,如Context;控制应用程序的多个生命周期;发送UI事件给应用程序;在执行期间检查程序状态。Instrumentation框架通过将主程序和测试程序运行在同一个进程来实现这些功能。

通过在测试工程的manifest文件中添加<instrumentation>元素来指定要测试的应用程序。这个元素的特性指明了要测试的应用程序包名,以及告诉Android如何运行测试程序。在Inustrumentation TestRunner章节有更多的细节描述。

下面的图片概要的描述了Android的测试环境:

在Android中,测试程序也是Android程序,因此,它和被测试程序的书写方式有很多相同的地方。SDK工具能帮助你同时创建主程序工程及它的测试工程。你可以通过Eclipse的ADT插件或者命令行来运行Android测试。Eclipse的ADT提供了大量的工具来创建测试用例,运行以及查看结果。

Testing API

Android提供了基于JUnit测试框架的测试API来书写测试用例和测试程序。另外,Android还提供了强大的Instrumentation框架,允许测试用例访问程序的状态及运行时对象。

下面的章节描述了Android中可利用的主要测试API。

JUnit TestCase类

继承自JUnit的TestCase,不能使用Instrumentation框架。但这些类包含访问系统对象(如Context)的方法。使用Context,你可以浏览资源,文件,数据库等等。基类是AndroidTestCase,一般常见的是它的子类,和特定组件关联。

子类有:

l   ApplicationTestCase——测试整个应用程序的类。它允许你注入一个模拟的Context到应用程序中,在应用程序启动之前初始化测试参数,并在应用程序结束之后销毁之前检查应用程序。

l   ProviderTestCase2——测试单个ContentProvider的类。因为它要求使用MockContentResolver,并注入一个IsolatedContext,因此Provider的测试是与OS孤立的。

l   ServiceTestCase——测试单个Service的类。你可以注入一个模拟的Context或模拟的Application(或者两者),或者让Android为你提供Context和MockApplication。

Instrumentation TestCase类

继承自JUnit TestCase类,并可以使用Instrumentation框架,用于测试Activity。使用Instrumentation,Android可以向程序发送事件来自动进行UI测试,并可以精确控制Activity的启动,监测Activity生命周期的状态。

基类是InstrumentationTestCase。它的所有子类都能发送按键或触摸事件给UI。子类还可以注入一个模拟的Intent。

子类有:

l   ActivityTestCase——Activity测试类的基类。

l   SingleLaunchActivityTestCase——测试单个Activity的类。它能触发一次setup()和tearDown(),而不是每个方法调用时都触发。如果你的测试方法都是针对同一个Activity的话,那就使用它吧。

l   SyncBaseInstrumentation——测试Content Provider同步性的类。它使用Instrumentation在启动测试同步性之前取消已经存在的同步对象。

l   ActivityUnitTestCase——对单个Activity进行单一测试的类。使用它,你可以注入模拟的Context或Application,或者两者。它用于对Activity进行单元测试。

不同于其它的Instrumentation类,这个测试类不能注入模拟的Intent。

l   ActivityInstrumentationTestCase2——在正常的系统环境中测试单个Activity的类。你不能注入一个模拟的Context,但你可以注入一个模拟的Intent。另外,你还可以在UI线程(应用程序的主线程)运行测试方法,并且可以给应用程序UI发送按键及触摸事件。

Assert类

Android还继承了JUnit的Assert类,其中,有两个子类,MoreAsserts和ViewAsserts:

l   MoreAsserts类包含更多强大的断言方法,如assertContainsRegex(String, String),可以作正则表达式的匹配。

l   ViewAsserts类包含关于Android View的有用断言方法,如assertHasScreenCoordinates(View, View, int, int),可以测试View在可视区域的特定X、Y位置。这些Assert简化了UI中几何图形和对齐方式的测试。

Mock对象类

Android有一些类可以方便的创建模拟的系统对象,如Application,Context,Content Resolver和Resource。Android还在一些测试类中提供了一些方法来创建模拟的Intent。因为这些模拟的对象比实际对象更容易使用,因此,使用它们能简化依赖注入。你可以在android.test和android.test.mock中找到这些类。

它们是:

l   IsolatedContext——模拟一个Context,这样应用程序可以孤立运行。与此同时,还有大量的代码帮助我们完成与Context的通信。这个类在单元测试时很有用。

l   RenamingDelegatingContext——当修改默认的文件和数据库名时,可以委托大多数的函数到一个存在的、常规的Context上。使用这个类来测试文件和数据库与正常的系统Context之间的操作。

l   MockApplication,MockContentResolver,MockContext,MockDialogInterface,MockPackageManager,MockResources——创建模拟的系统对象的类。它们只暴露那些对对象的管理有用的方法。这些方法的默认实现只是抛出异常。你需要继承这些类并重写这些方法。

Instrumentation TestRunner

Android提供了自定义的运行测试用例的类,叫做InstrumentationTestRunner。这个类控制应用程序处于测试环境中,在同一个进程中运行测试程序和主程序,并且将测试结果输出到合适的地方。IntrumentationTestRunner在运行时对整个测试环境的控制能力的关键是使用Instrumentation。注意,如果你的测试类不使用Instrumentation的话,你也可以使用这个TestRunner。

当你运行一个测试程序时,首先会运行一个系统工具叫做Activity Manager。Activity Manager使用Instrumentation框架来启动和控制TestRunner,这个TestRunner反过来又使用Intrumentation来关闭任何主程序的实例,然后启动测试程序及主程序(同一个进程中)。这就能确保测试程序与主程序间的直接交互。

在测试环境中工作

对Android程序的测试都包含在一个测试程序里,它本身也是一个Android应用程序。测试程序以单独的Android工程存在,与正常的Android程序有着相同的文件和文件夹。测试工程通过在manifest文件中指定要测试的应用程序。

每个测试程序包含一个或多个针对特定类型组件的测试用例。测试用例里定义了测试应用程序某些部分的测试方法。当你运行测试程序,Android会在相同进程里加载主程序,然后触发每个测试用例里的测试方法。

测试工程

为了开始对一个Android程序测试,你需要使用Android工具创建一个测试工程。工具会创建工程文件夹、文件和所需的子文件夹。工具还会创建一个manifest文件,指定被测试的应用程序。

测试用例

一个测试程序包含一个或多个测试用例,它们都继承自Android TestCase类。选择一个测试用例类取决于你要测试的Android组件的类型以及你要做什么样的测试。一个测试程序可以测试不同的组件,但每个测试用例类设计时只能测试单一类型的组件。

一些Android组件有多个关联的测试用例类。在这种情况下,在可选择的类间,你需要判断你要进行的测试类型。例如,对于Activity来说,你有两个选择,ActivityInstrumentationTestCase2和ActivityUnitTestCase。

ActivityInstrumentationTestCase2设计用于进行一些功能性的测试,因此,它在一个正常的系统环境中测试Activity。你可以注入模拟的Intent,但不能是模拟的Context。一般来说,你不能模拟Activity间的依赖关系。

相比而言,ActivityUnitTestCase设计用于单元测试,因此,它在一个孤立的系统环境中测试Activity。换句话说,当你使用这个测试类时,Activity不能与其它Activity交互。

作为一个经验法则,如果你想测试Activity与Android的交互的话,使用ActivityInstrumentationTestCase2。如果你想对一个Activity做回归测试的话,使用ActivityUnitTestCase。

测试方法

每个测试用例类提供了可以建立测试环境和控制应用程序的方法。例如,所有的测试用例类都提供了JUnit的setUp()方法来搭建测试环境。另外,你可以添加方法来定义单独的测试。当你运行测试程序时,每个添加的方法都会运行一次。如果你重写了setUp()方法,它会在每个方法运行前运行。相似的,tearDown()方法会在每个方法之后运行。

测试用例类提供了大量的对组件启动和停止控制的方法。由于这个原因,在运行测试之前,你需要明确告诉Android启动一个组件。例如,你可以使用getActivity()来启动一个Activity。在整个测试用例期间,你只能调用这个方法一次,或者每个测试方法一次。甚至你可以在单个测试方法中,调用它的finishing()来销毁Activity,然后再调用getActivity()重新启动一个。

运行测试并查看结果

编译完测试工程后,你就可以使用系统工具Activity Manager来运行测试程序。你给Activity Manager提供了TestRunner的名(一般是InstrumentationTestRunner,在程序中指定);名包括被测试程序的包名和TestRunner的名。Activity Manager加载并启动你的测试程序,杀死主程序的任何实例,然后在测试程序的同一个进程里加载主程序,然后传递测试程序的第一个测试用例。这个时候,TestRunner会接管这些测试用例,运行里面的每个测试方法,直到所有的方法运行结束。

如果你使用Eclipse,结果会在JUnit的面板中显示。如果你使用命令行,将输出到STDOUT上。

测试什么?

除了一些功能测试外,这里还有一些你应该考虑测试的内容:

l   Activity生命周期事件:你应该测试Activity处理生命周期事件的正确性。例如,一个Activity应该在pause或destroy事件时保存它的状态。记住一点的是屏幕方向的改变也会引发当前Activity销毁,因此,你需要测试这种偶然情况确保不会丢失应用程序状态。

l   数据库操作:你应该确保数据库操作能正确处理应用程序状态的变化。使用android.test.mock中的模拟对象。

l   屏幕大小和分辨率:在发布程序之前,确保在所有要运行的屏幕大小和分辨率上测试通过。你可以使用AVD来测试,或者使用真实的目标设备进行测试。

附加:UI测试

接下来的章节为应用程序UI的测试提供了一些提示,特别是帮助你在UI线程里处理动作,触屏和按键事件,和锁屏。

UI线程中测试

Activity运行在程序的UI线程里。一旦UI初始化后,例如在Activity的onCreate()方法后,所有与UI的交互都必须运行在UI线程里。当你正常运行程序时,它有权限可以访问这个线程,并且不会出现什么特别的事情。

当你运行测试程序时,这一点发生了变化。在带有instrumentation的类里,你可以触发方法在UI线程里运行。其它的测试用例类不允许这么做。为了一个完整的测试方法都在UI线程里运行,你可以使用@UIThreadTest来声明线程。注意,这将会在UI线程里运行方法里所有的语句。不与UI交互的方法不允许这么做;例如,你不能触发Instrumentation.waitForIdleSync()。

如果让方法中的一部分代码运行在UI线程的话,创建一个匿名的Runnable对象,把代码放到run()方法中,然后把这个对象传递给appActivity.runOnUiThread(),在这里,appActivity就是你要测试的app对象。
分享到:
评论

相关推荐

    TMS_Instrumentation_Workshop_v2010_-_XE3.7z

    通过深入研究《TMS_Instrumentation_Workshop_v2010_-_XE3》的内容,Delphi开发者可以提升自己的专业技能,为创建更高效、更稳定的应用程序打下坚实基础。同时,了解并熟练运用这套工具,也能帮助开发者节省大量时间...

    TMS Instrumentation Workshop 2.0.0.0 Full Source D5-XE7.7z

    源代码的提供不仅有助于学习和调试,也为有特殊需求的开发者提供了修改和优化组件的基础。 总之,TMS Instrumentation Workshop 2.0.0.0 是 Delphi 开发者的重要辅助工具,它以丰富的组件库、强大的报告生成器和...

    Real World Instrumentation with Python

    《Real World Instrumentation with Python》是一本专注于使用Python语言进行实际仪器控制与数据采集的书籍。这本书深入浅出地介绍了如何利用Python的强大功能来处理硬件交互、数据收集和分析的各种问题,尤其适合...

    Fundamentals of Instrumentation and Measurement .pdf

    ### 仪器与测量基础知识点概览 #### 一、引言 《仪器与测量基础》是一本详尽介绍仪器仪表...通过学习本书,读者可以深入了解传感器的工作原理、信号处理技术和复杂的系统设计方法,为解决实际问题提供坚实的理论基础。

    Real World Instrumentation with Python-带书签目录超清文字版

    《Real World Instrumentation with Python》是一本专注于使用Python语言进行实际仪器控制与数据采集的书籍。这本书的内容旨在帮助读者理解如何利用Python的强大功能来处理硬件设备,进行实验数据的实时监控和分析,...

    安卓UiAutomator/UiDevice/Instrumentation官方测试范例

    `Instrumentation`是Android系统提供的另一个测试框架,它是所有Android应用测试的基础。它允许开发者在应用运行时控制和监视应用的行为。Instrumentation可以启动、停止、控制被测应用,以及注入事件到应用的生命...

    安卓基础学习笔记(附带代码案例)

    安卓基础学习笔记(附带代码案例) 本资源摘要信息主要讲解了安卓基础学习笔记的相关知识点,涵盖了安卓开发环境的搭建、基础技术知识点说明以及详细的测试案例代码。下面是相关知识点的详细解释: 一、安卓开发...

    Power Electronics and Instrumentation Enginee

    ### 标题:Power Electronics and Instrumentation Engineering #### 关键知识点: 1. **电力电子技术**:该领域涉及电力转换和控制的技术,包括但不限于变频器、整流器、逆变器等设备的设计与应用。 2. **仪器...

    Virtual-Instrumentation-Using-Labview

    总的来说,"Virtual-Instrumentation-Using-Labview"这本书将引导读者深入理解虚拟仪器的概念,掌握LabVIEW的使用技巧,从而在各自的领域中实现创新的测量和控制系统设计。通过学习,不仅可以提高工作效率,还能解决...

    Appium学习指南

    学习这些内容之前,建议学习者具备一些基础知识,如Android开发的基础、Android SDK工具的熟悉、命令行的使用以及Java或Python语言基础。 学习指南的目标是帮助读者搭建Java和Android开发环境,安装Appium以及...

    Spring基础学习,适合新人

    【Spring基础学习,适合新人】 在Java后端开发领域,Spring框架是一个不可或缺的工具,尤其对于初学者来说,理解并掌握Spring的基本概念和技术是至关重要的。Spring以其控制反转(IoC)和面向切面编程(AOP)为核心...

    Intelligent Sensing, Instrumentation and Measurements

    《智能感知、仪表与测量》是一本深入探讨现代科技领域中关键核心技术的著作。该书主要聚焦于如何利用先进的...通过对这些知识点的学习,读者不仅可以掌握当前的技术发展趋势,还能为未来创新提供理论基础和实践指导。

    Real World Instrumentation with Python-带书签目录超清文字版.pdf

    - **第1章:仪器仪表简介**:这一章节涵盖了数据采集的基础知识,包括控制输出、开环控制、闭环控制、顺序控制等内容,并概述了不同领域的应用实例,如电子测试仪器、实验室仪器仪表和过程控制等。 - **第2章:...

    CAD工作学习(CAD、CAD二次开发、C#学习)

    在本学习计划中,我们将学习CAD的基本操作、EICAD的入门学习、CAD二次开发的基本概念,以及C#编程语言的基础知识。 一、CAD基本操作 CAD是计算机辅助设计的缩写,指的是使用计算机来进行图形设计和drafting的过程...

    java项目实现热更源码-javaagent

    这个Agent需要包含`premain`或`agentmain`方法,用于接收Instrumentation实例,并在此基础上进行类的动态加载或替换。 2. **指定Agent参数**:在Java应用启动时,通过`-javaagent`参数指定Agent的路径和可选参数。...

    jmx第一个学习例子

    标题和描述均提到了“jmx第一个学习例子”,这标志着文章旨在引导读者通过一个实践性的示例理解Java Management Extensions(JMX)的基础概念和技术。JMX作为一项由Sun Microsystems(现Oracle)提出的技术,用于...

    学习使用WMI管理网络

    - **WMI简介**:Windows Management Instrumentation(WMI)是一种内置在Windows操作系统中的技术,用于远程管理和监控Windows设备的状态。 - **命名空间的理解**:WMI通过命名空间来组织其管理对象和服务,类似于...

    LabVIEW 学习网站

    LabVIEW(Laboratory Virtual Instrumentation Engineering Workbench)是由National Instruments(NI)开发的一款图形化编程环境,它允许用户通过直观的图形界面进行编程,极大地简化了数据采集、信号处理、分析和...

    Android自动化测试之Robotium--基础操作

    在Robotium简介中提到,它在Instrumentation API的基础上提供了更多操作控件的函数,其控件搜索功能封装得比较好。Robotium还支持查看bug点以及集成测试结束时统计的多种覆盖率结果。 最后,对于Android自动化测试...

    j2se一句话学习笔记

    Java SE(J2SE)是Java平台标准版的简称,它是Java开发环境的基础,提供了丰富的类库和API供开发者使用。以下是对标题和描述中涉及的一些知识点的详细解释: 1. **Desktop类**:`java.awt.Desktop`类允许用户通过...

Global site tag (gtag.js) - Google Analytics