Android测试教程


一、 

测试项目

  

Android的编译和测试工具需要测试项目组织符合预订的结构:分别为Test case 类,Test case 包以及测试项目。

JUnit 为Android的测试的基础,一般来说,一个JUint测试为一个用来测试一个应用某一部分的语句。 你可以将多个测试Test方法组织起来构成一个测试用例(Test case),多个测试用例可以构成Test Suites 。 每个Test方法相对独立,一个测试类Test class包含一组相关的Test 或其它辅助方法。

在Android平台上,你可以使用测试工具调入Test Package和所要测试的应用,然后执行Test Runner来运行测试用例。

使用Eclipse ADT 工具创建测试项目的方法:

1. 在创建应用的同时创建测试项目,如下图

Android测试教程_第1张图片

选中Create a Test Project ,ADT自动为应用创建对应的测试项目

2. 导入已有的测试项目,并和被测试的应用关联。

Android SDK 自带ApiDemo,并带有其对应的测试项目ApiDemos->Test. 打开ApiDemos->Test 的方法如下,首先是选中Build Target (比如Android 2.2),然后选择Create project from existing sample, 从下拉列表中选择ApiDemos ->Tests (注意你要先创建ApiDemos Android ApiDemos示例解析(1):创建ApiDemo示例)

将ApiDemos->tests 和ApiDemos 关联起来:

修改ApiDemos->tests 测试项目的属性,在Java Build Path 的项目Projects 中添加ApiDemos

Android测试教程_第2张图片

你最好使Eclipse 工具创建测试项目:

  • 自动为你的测试项目设置使用InstrumentationTestRunner 作为运行Test Package的Test Runner,测试项目必须使用InstrumentationTestRunner 或其子类做为Test Package的runner.
  • 为测试项目创建合适的项目名称和测试包名称,比如你需要测试的应用的包名称为com.mydomain.myapp 则自动创建的测试包名为com.mydomain.myapp.test ,从测试包名可以很容易找到对应的应用程序包名称。
  • 自动创建合适的build 文件,mainifest 文件和文件目录结构。

建议使用的文件目录结构可以如下所示:

MyProject/
—–AndroidManifest.xml
—–res/
——–… (resources for main application)
—–src/
——–… (source code for main application) …
—–tests/
———-AndroidManifest.xml
———-res/
————-… (resources for tests)
———-src/
————-… (source code for tests)


二、测试相关API

Android的测试框架相关的API主要定义在三个包中:

  • android.test 用于编写Android测试用例
  • android.test.mock 定义了方便测试用的测试“桩”类
  • android.test.suitebuilder 运行测试用例的Test Runner类

Android 测试API 是基于JUnit 扩展而来,并添加了与Android平台相关的测试API。

JUnit

你可以直接使用JUnit中相关API编写一些和平台无关的测试用例(基于TestCase), Android 测试API中提供了一个TestCase的子类AndroidTestCase ,可以用来编写一些Android相关的对象的测试用例,AndroidTestCase 支持一些和平台相关的setup,teardown 以及setup 方法。

你也可以直接使用JUnit 的Assert 方法 显示测试结果,这些Assert方法可以通过比较预期的值和实际的值,如果不同可以排除异常。Android 测试API扩展了一些Assert方法用于支持和Android平台相关的比较。

要注意的是,Android 测试API支持JUnit 3 代码风格,而不支持JUnit 4 代码风格,也只能使用InstrumentationTestRunner 来运行测试用例。

Instrumentation

Android 的Instrumentation 提供了一些“钩子”方法连接到Android操作系统中,可以独立控制Android组件(Activity,Service等)的生命周期,并可以控制Android如何调用一个应用。

在通常情况下(普通的Android应用),Android的activity,Service等的生命周期是由
Android操作系统来控制的。 比如一个Activity 的生命周期开始于onCreate (由某个Intent激活),然后是onResume. 可以参见Android简明开发教程五:Activities。 应用程序本身无法直接控制这些生命周期状态的切换。但使用Instrumatation API时你可以直接调用这些方法。

Instrumentation API 也可以支持强制某个应用和另一个已经在运作的应用运行在同一个进程中,这在通常的情况下是不可能实现的。

使用Instrumentation API 你可以直接调用Activity或是Service的生命周期回调函数,从而可以让你运行一步一步的运行Activity或是Service的生命周期函数。如下例显示了如何使用Instrumentation API来测试Activity 保持和恢复State。

[java]  view plain copy print ?
  1. // Start the main activity of the  
  2. // application under test  
  3. mActivity = getActivity();  
  4.    
  5. // Get a handle to the Activity object's  
  6. //main UI widget, a Spinner  
  7. mSpinner  
  8. = (Spinner)mActivity  
  9.  .findViewById(com.android.example.spinner.R.id.Spinner01);  
  10.    
  11. // Set the Spinner to a known position  
  12. mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);  
  13.    
  14. // Stop the activity - The onDestroy()  
  15. //method should save the state of the Spinner  
  16. mActivity.finish();  
  17.    
  18. // Re-start the Activity - the onResume()  
  19. //method should restore the state of the Spinner  
  20. mActivity = getActivity();  
  21.    
  22. // Get the Spinner's current position  
  23. int currentPosition = mActivity.getSpinnerPosition();  
  24.    
  25. // Assert that the current position is the  
  26. //same as the starting position  
  27. assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);  


 

其中关键的一个方法是getActivity(),只有调用getActivity()后被测试的activity才会启动。此外Instrumentation API允许把测试项目和被测试的应用项目运行到同一个进程中,从而在测试代码中可以直接调用被测试应用的方法和访问其成员。

Test case 相关类

Android提供了多个由Testcase或Assert派生而来的子类以支持Android平台相关的setup,teardown 和其它辅助方法。

  • AndroidTestCase 为一Android平台下通用的测试类,它支持所有JUnit的Assert方法和标准的setUp 和tearDown 方法,并可以用来测试Android permission 。
  • 组件相关的测试类如测试activity, Content provider ,Service 相关的测试类,Android没有提供单独的用来测试BroadcastReceiver 的测试类,而是可以通过发送Intent对象来检测Broadcast Receiver的反应结果来测试BroadcastReceiver。
  • ApplicationTestCase 可以用来测试Application 对象。
  • InstrumentationTestCase 如果你要使用Instrumentation API,那么你必须使用InstrumentationTestCase或其子类。

Assertion classes

Android测试中可以使用JUnit中提供的Assert方法来显示测试结果。除此之外,Testing API还提供了MoreAsserts 和ViewAsserts 类。其中MoreAsserts支持更多的比较方法包括RegEx(正则)比较等。ViewAsserts 可以用来校验UI View。

Mock object classes

android.test.mock 包中定义一些测试“桩”类,如MockApplication,MockContentProvider ,MockContext,MockCursor, MockPackagManager等用例帮助测试。

后面将具体介绍如何使用这些API来编写测试用例。


三、测试项目HelloWorldTest

本例介绍创建一个测试项目的一般步骤和编写测试用例的基本方法。

为简单起见,创建一个HelloWorld应用,带有一个Greeting类,其定义如下:

[java]  view plain copy print ?
  1. public class Greeting {  
  2.  private String name;  
  3.    
  4.  public Greeting(String name){  
  5.  this.name=name;  
  6.  }  
  7.    
  8.  public String getGreetings(){  
  9.  return "Hello," +name;  
  10.  }  
  11.    
  12. }  


 

测试项目打算来测试这个Greeting 类的getGreetings的方法,比如说,创建Greeting(“World”) ,预期的getGreetings 的值应为”Hello,World”。我们可以使用JUnit框架来编写一个测试用例。

这里我们在创建HelloWorld的项目的同时创建一个测试项目,参见Android测试教程(3):测试项目

Android测试教程_第3张图片

可以看到新创建的测试项目名称为HelloWorldTest ,并在src 中创建了com.pstreets.demo.test 文件夹(和HelloWorld 应用的com.pstreets.demo 包相对应)。但src 还没有任何代码。

可以看到HelloWorldTest 属性的Java Build Path-> Projects 中引用的Project为HelloWorld, 表示在HelloWorldTest 项目中可以引用HelloWorld 项目中的类。

然后在HelloWorldTest的src 的com.pstreets.demo.test 中添加一个AllTests.java,其定义如下:

[java]  view plain copy print ?
  1. public class AllTests extends TestSuite {  
  2.    
  3.  public static Test suite() {  
  4.  return new TestSuiteBuilder(AllTests.class)  
  5.  .includeAllPackagesUnderHere()  
  6.  .build();  
  7.  }  
  8. }  

AllTests.java 一般可以不用修改的应用到大部分的测试项目中,如果有特殊需要,可以使用android.test.suitebuilder 的类定义那些Testcase 需要包含到最终的测试包(Test Suite)中.

定义了AllTests.java ,这个测试项目就基本完整了,也可以运行了,只是还没有定义任何测试用例(Test case) 。

这里定义一个GreetingTest ,用于测试Greeting 类:

[java]  view plain copy print ?
  1. public class GreetingTest extends TestCase {  
  2.    
  3.  Greeting greeting;  
  4.    
  5.  @Override  
  6.  public void setUp(){  
  7.  greeting=new Greeting("World");  
  8.    
  9.  }  
  10.    
  11.  @Override  
  12.  public void tearDown(){  
  13.    
  14.  }  
  15.    
  16.  public void testGetGreeting() {  
  17.  assertTrue(greeting.getGreetings()  
  18.  .compareToIgnoreCase("Hello,World")==0);  
  19.  }  
  20.    
  21. }  

其实对于与这个例子setUp和tearDown 不是必须的,如果多个TestCase 使用同一组测试数据,可以在setUp 中创建这些测试数据,JUnit 中运行每个TestCase 前会运行setUp ,运行TestCase 后会执行tearDown 。

JUnit 把以test开头的方法作为一个实例,也可以使用annotation @Test 表示一个方法为测试方法。

GreetingTest 由TestCase 派生,因为这里测试是一个普通Java类(和Android 平台无关),也可以使用AndroidTestCase 作为基类。

testGetGreeting 使用assertTrue 来检测测试结果,预期的getGreetings()的值为”Hello,World” ,如果为true ,表示测试通过。

以Android JUint Test 的方式运行HelloWorldTest

Android测试教程_第4张图片运行HelloWorldTest 时,Android测试环境会自动启动HelloWorld ,并在JUint 窗口显示最终测试结果。

Android测试教程_第5张图片

在开发应用过程中,可以一边编写应用,一边编写测试用例。


http://blog.csdn.net/column/details/mapdigittesting.html

你可能感兴趣的:(Android测试教程)