Android的测试介绍

你应该把编写和运行测试作为你Android应用开发周期的一部分,编写好的测试可以帮助你在开发过程中尽早发现漏洞,并让你对自己的代码更有信心。
测试用例定义了一系列对象和方法从而独立进行多个测试,测试用例可以编写成测试组并按计划的运行,由测试框架组织成一个可以重复运行的测试者。   Android基于最流行的JUnit框架来自定义测试框架,你可以编写测试用例来测试你应用程序的特定行为,并在不用的Android设备上检测一致性,你的测试用例也可以通过描述应用组件的预期行为来作为内部代码注释文档。
一、测试类和常用判断语句
TestCase类
测试是一个普通Java类(和Android 平台无关),也可以使用AndroidTestCase 作为基类。
AndroidTestCase类
继承至TestCast类。
ActivityInstrumentationTestCase2类

Activity的测试非常依赖于Android的Instrumation 框架,和Android其他组件不同的是,Activity具有复杂的生命周期回调函数(如onCreate, onStart 等) ,通常情况下除通过Instrumation 接口外不能直接调用这些回调函数。

  • 测试Activity的基本测试类为InstrumentationTestCase,它提供了Instrumentation接口给TestCase的子类。 为了支持Activity测试,InstrumentationTestCase提供了下面功能:
  • 生命周期控制: 使用Instrumentation,你可以启动,暂停,中止被测试的Activity。
  • Dependency Injection : Instrumentation允许创建一些Mock对象如Context,Application来帮助测试Activity,从而帮助你控制测试环境并和实际的应用的其他部分隔离开来。你也可以定制一些Intent以启动Activity。
  • 用户界面交互: 你可以使用Instrumentation向UI发送按键和触摸事件。 
常用方法:
setUp():在执行任何代码测试之前自动执行,和类的构造器一样。用于初始化数据。
tearDown():如activity的Destory。在销毁对象和关闭资源链接等。
常用判断:  
assertNotNull(actual);断言不为null
assertEquals(expected,actual),断言actual与猜测的expected值是否相同。
assertTrue(boolean):断言为真

二、测试环境配置
方法有种:
第一种是通过自动创建。点击new Project>Android Test Project>命名>选择所要测试的项目>完成。
第二种是通过手动配置完成。如图:
  
  
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="hb.learn.junit"
      android:versionCode="1"
      android:versionName="1.0">
<!-- 确保minSdkVersion的属性是8或者更高 -->
    <uses-sdk android:minSdkVersion="8" />
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <!-- 在本应用中导入需要使用的包,放在application里面activity外面 -->
        <uses-library android:name="android.test.runner" />
    </application>   
    <!-- 记住这个一要放在application外面,不然会出现配置错误信息,targetPackage是被测试的的程序包名 -->
    <instrumentation android:name="android.test.InstrumentationTestRunner"
          android:targetPackage="hb.learn.junit" android:label="Tests for My App" />
</manifest>
按照惯例,测试包的名称应该遵循与应用包名相同的命名方式,在应用包名后接“.tests”。在你创建的测试包,为你的测试用例添加 Java 类。
你的测试用例名称也应遵循你要测试的Java或 Android 的类相同的名称,但后缀为“Test”。

三、测试UI组件
通常情况下,你的 Activity ,包括用户界面组件(如按钮,复选框,可编辑的文本域,和选框)允许你的用户与Android应用程序交互。本节介绍如何用一个简单的按钮的界面交互测试。你可以使用相同的步骤来测试其他的,更复杂的UI组件。

UI测试目标

首先初始化测试程序环境

  
  
@Override
protected void setUp() throws Exception {
        super.setUp();
        setActivityInitialTouchMode(true);
        mainActivity = getActivity();
        btn = (Button)mainActivity.findViewById(R.id.button1);
        tv = (TextView) mainActivity.findViewById(R.id.textView1);
        intent = new Intent(getInstrumentation().getTargetContext(),MainActivity.class);
}  

检查程序 初始化 测试参数
   
   
public void testPreconditions() {
        assertNotNull("mainActivity is null"mainActivity);
        assertNotNull("btn is null"btn);
        assertNotNull("tv is null"tv);
}  

例一:检验Activity启动时Button是按照正确布局显示的。

@MediumTest
public void testClickMeButton_layout() {
    final View decorView = mClickFunActivity.getWindow().getDecorView();
    ViewAsserts.assertOnScreen(decorView, mClickMeButton);
    final ViewGroup.LayoutParams layoutParams = mClickMeButton.getLayoutParams();
    assertNotNull(layoutParams);
    assertEquals(layoutParams.width, WindowManager.LayoutParams.MATCH_PARENT);
    assertEquals(layoutParams.height, WindowManager.LayoutParams.WRAP_CONTENT);
}

在调用assertOnScreen())方法时,你传递根视图以及你期望呈现在屏幕上的视图作为参数。如果你想呈现的视图没有在根视图中,该方法会抛出一个AssertionFailedError异常,除非测试通过。

你也可以通过获取一个ViewGroup.LayoutParams对象的引用验证Button布局是否正确,然后调用声明方法验证Button对象的宽高属性值是否与预期值一致。

例二:检验TextView的布局参数

@MediumTest
public void testInfoTextView_layout() {
    final View decorView = mClickFunActivity.getWindow().getDecorView();
    ViewAsserts.assertOnScreen(decorView, mInfoTextView);
    assertTrue(View.GONE == mInfoTextView.getVisibility());
}

在调用 assertOnScreen() )方法时,你传递根视图以及你期望呈现在屏幕上的视图作为参数。如果你想呈现的视图没有在根视图中,该方法会抛出一个 AssertionFailedError 异常,除非测试通过。
例二: 检验按钮的 行为。
@MediumTest
public void testClickMeButton_clickButtonAndExpectInfoText() {
    String expectedInfoText = mClickFunActivity.getString(R.string.info_text);
    TouchUtils.clickView(this, mClickMeButton);
    assertTrue(View.VISIBLE == mInfoTextView.getVisibility());
    assertEquals(expectedInfoText, mInfoTextView.getText());
}
  注意 : Touchutils 助手类提供与应用程序交互的方法可以方便进行模拟触摸操作。你可以使用这些方法来模拟点击,轻敲,或应用程序屏幕拖动View。

警告Touchutils方法的目的是将事件安全地从测试线程发送到UI线程。你不应该用Touchutils直接在UI线程或任何标注@UIThread的测试方法这样做可能会增加错误线程异常。

释介绍:通常情况下,只需要几毫秒的时间的应该被标记为@SmallTest,长时间运行的测试(100毫秒或更多)通常被标记为@MediumTest,@LargeTest,主要取决于测试访问资源在网络上或在本地系统。

四、单元测试

一个Activity测试单元是快速验证一个Activity的状态以及与其它独立组件(也就是和系统其它部分分离的部分)交互的最优方式。一个测试单元通常是测试代码中可能性最小的代码块(可以是一个方法,类,或者组件),而且也不依赖于系统或网络资源。比如说,你可以写一个测试单元去检查Activity是否有正确的布局或者它的触发器,以及Intent对象的正确性。

测试单元一般不适合测试与系统有复杂交互事件的UI。相反,你应该使用像ActivityInstrumentationTestCase2的类作为测试UI组建的描述。

测试目标:

  • 验证当Button被按下是启动的LaunchActivity是否正确。

  • 验证启动的Intent是否包含有效的数据。

继承ActiviUnitTestCase的Activity不会被Android自动启动的。要单独启动Activity,你需要显式的调用startActivity()方法,并传递一个Intent来启动你的目标Activity

public class LaunchActivityTest extends ActivityUnitTestCase<LaunchActivity> {
    ...
    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mLaunchIntent = new Intent(getInstrumentation()
                .getTargetContext(), LaunchActivity.class);
        startActivity(mLaunchIntent, null, null);
        final Button launchNextButton =(Button) getActivity().findViewById(R.id.launch_next_activity_button);
    }
}
例一:验证一个activity的启动

@MediumTest
public void testNextActivityWasLaunchedWithIntent() {
    launchNextButton.performClick();
    final Intent launchIntent = getStartedActivityIntent();
    assertNotNull("Intent was null", launchIntent);
    final String payload = launchIntent.getStringExtra(NextActivity.EXTRAS_PAYLOAD_KEY);
    assertEquals("Payload is empty", "hello world", payload);
}

Activity的代码:
  
  
 public static final String EXTRAS_PAYLOAD_KEY="hello";
 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }
 public void onShowActivity(View v) {
     Intent intent = new Intent(this,SecondActivity.class);
     intent.putExtra(EXTRAS_PAYLOAD_KEY"hello world");
     startActivity(intent);
 }    
因为LaunchActivity是独立运行的,所以不可以使用 TouchUtils 库来操作UI。要正确处理 Button 点击,你可以调用 perfoemClick() )方法。
ActivityUnitTestCase ActivityInstrumentationTestCase2 不同的是在 ActivityInstrumentationTestCase2 中可以与Android系统通信以及发送键盘输入和点击事件到UI。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值