单元测试instrumentation入门---eclipse

前言:进公司要先做两个月测试,我了个去,对测试是不大了解啊,在测试主管的指导下学instrumentation接口,好像还挺好用的,看到一篇文章将其稍做补充摘录于下,分享给大家。


参考文章地址:《Android单元测试初探——Instrumentation》    这里与原文有些出入,有些不必要的部分我将其去掉了,并增加了一些知识。


正文

首先,我们来了解一下android的测试类的层次结构:

单元测试instrumentation入门---eclipse_第1张图片

可以看出android中的测试方法主要有AndroidTextCase和InstrumentationTextCase。在这篇文章中,我将介绍Instrumentation这种测试方法,那么什么是Instrumentation?

Instrumentation和Activity有点类似,只不过Activity是需要一个界面的,而Instrumentation并不是这样的,我们可以将它理解为一种没有图形界面的,具有启动能力的,用于监控其他类(用Target Package声明)的工具类。

下面通过一个简单的例子来讲解Instrumentation的基本测试方法。

1.首先建立一个Android project,类名为test,代码如下:

package com.example.test;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends Activity {

	TextView myText;
	Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
      myText = (TextView) findViewById(R.id.text1);
      button = (Button) findViewById(R.id.btn1);
      button.setOnClickListener(new OnClickListener() {
          @Override
          public void onClick(View arg0) {
              myText.setText("Hello Android");
          }
      });
    }
    
    public int add(int i, int j) {
        return (i + j);
    }
}
对应的xml布局代码如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.test.MainActivity" >

    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    <Button android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hellowrold Btn" />

</RelativeLayout>
这个程序的功能比较简单,点击按钮之后,TextView的内容由Hello变为Hello Android.同时,在这个类中,我还写了一个简单的add方法,没有被调用,仅供测试而已。

2. 在src文件夹中添加一个测试包,在测试包中添加一个测试类SampleTest

单元测试instrumentation入门---eclipse_第2张图片

测试类的代码如下:

package com.example.sample.test;

import com.example.test.*;
import android.content.Intent;
import android.os.SystemClock;
import android.test.InstrumentationTestCase;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
  
public class Sampletest extends InstrumentationTestCase {
    private MainActivity sample = null;
    private Button button = null;
    private TextView text = null;
  
    /*
     * 初始设置
     * @see junit.framework.TestCase#setUp()
     */
    @Override
    protected void setUp()  {
        try {
            super.setUp();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Intent intent = new Intent();
        intent.setClassName("com.example.test", MainActivity.class.getName());
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        sample = (MainActivity) getInstrumentation().startActivitySync(intent);
        text = (TextView) sample.findViewById(R.id.text1);
        button = (Button) sample.findViewById(R.id.btn1);
    }
  
    /*
     * 垃圾清理与资源回收
     * @see android.test.InstrumentationTestCase#tearDown()
     */
    @Override
    protected void tearDown()  {
        sample.finish();
        try {
            super.tearDown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  
    /*
     * 活动功能测试
     */
    public void testActivity() throws Exception {
        Log.v("testActivity", "test the Activity");
        SystemClock.sleep(1500);//先sleep一会,这时大家看到的文字是hello
        
        for(int i=0;i<1000;i++)//点击1000次
        {
        	getInstrumentation().runOnMainSync(new PerformClick(button));
        }
        
        SystemClock.sleep(3000);//再sleep一会,这时大家看到的文字是Hello Android
        Log.v("testActivity",  text.getText().toString());
        assertEquals("Hello Android222", text.getText().toString());
        //注意,这里做了一个判断,判断当前text标签控件的文字是不是Hello Android222,当然不是,所以这句判断是错的!!!!
    }
  
    /*
     * 模拟按钮点击的接口
     */
    private class PerformClick implements Runnable {
        Button btn;
        public PerformClick(Button button) {
            btn = button;
        }
  
        public void run() {
            btn.performClick();
        }
    }
  
    /*
     * 测试类中的方法
     */
    public void testAdd() throws Exception{
        String tag = "testActivity";
        Log.v(tag, "test the method");
        int test = sample.add(1, 1);
        assertEquals(2, test);
    }
}
下面来简单讲解一下代码:
setUp()和tearDown()都是受保护的方法,通过继承可以覆写这些方法。


在android Developer中有如下的解释
protected void setUp ()
Since: API Level 3
Sets up the fixture, for example, open a network connection. This method is called before a test is executed.

protected void tearDown ()
Since: API Level 3
Make sure all resources are cleaned up and garbage collected before moving on to the next test. Subclasses that override this method should make sure they call super.tearDown() at the end of the overriding method.


setUp ()用来初始设置,如启动一个Activity,初始化资源等。
tearDown ()则用来垃圾清理与资源回收。

在testActivity()这个测试方法中,我模拟了一个按钮点击事件,然后来判断程序是否按照预期的执行。在这里PerformClick这个方法继承了Runnable接口,通过新的线程来执行模拟事件,之所以这么做,是因为如果直接在UI线程中运行可能会阻滞UI线程。

2.要想正确地执行测试,还需要修改AndroidManifest.xml这个文件.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.test"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="14" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
         <!--用于引入测试库-->
        <uses-library android:name="android.test.runner" />
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    
     <!--表示被测试的目标包与instrumentation的名称。-->
    <instrumentation android:targetPackage="com.example.test" android:name="android.test.InstrumentationTestRunner" />

</manifest>
这里添加了两行代码:

1、引入测试库:<uses-library android:name="android.test.runner" /> 这句是固定的,不允许任何更改

2、被测试的目标包与instrumentation的名称:<instrumentation android:targetPackage="com.example.test" android:name="android.test.InstrumentationTestRunner" />,其中目标包名就是我们要测试的包名,一定不要写错。

注意:关于这个包名是写哪个,可能总是有同学搞不清楚,看下面:参考网址:http://stackoverflow.com/questions/16591504/android-studio-import-existing-unit-tests-unable-to-find-instrumentation-info

单元测试instrumentation入门---eclipse_第3张图片

经过以上步骤,下面可以开始测试了。

用Eclipse集成的JUnit工具
在Eclipse中选择工程test,单击右键,在Run as子菜单选项中选择Android JUnit Test

单元测试instrumentation入门---eclipse_第4张图片

同时可以通过LogCat工具查看信息

单元测试instrumentation入门---eclipse_第5张图片

所以,instumentation可以实现自动测试,然后找出哪里的结果没有达到预期,并标出出错位置,我们只需要根据出错的位置断续调代码就好了。


源码来啦,地址:http://download.csdn.net/detail/harvic880925/7648933

请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/37924189  不胜感激……

你可能感兴趣的:(单元测试instrumentation入门---eclipse)