[Android初級]android單元測試之Activity單獨測試

有種情況,我們開發人員可能要對已經完成的應用做維護,其中某個界面可能存在bug,所以爲了測試某個可能存在問題的功能界面而從入口一直開始跳至該界面,這個情況,我們測試人員可以自己不停的跳過一些非測試目的界面,浪費了時間。這裏有個小的方式,是android提供的系統測試方案,可以來試試,今天我試了試Activity的單獨測試方式,感覺還不錯,在這裏分享給各位。

首先模擬一個我們要被測的項目:TestActivity和主要測試的登陸界面

需要測試的功能是,模擬用戶輸入,並登陸操作,以及重置功能的操作驗證。好,看我們下面怎麼實現吧

1.首先看看模擬項目中的代碼,就2個簡單的文件,一個模擬登陸的主界面,一個登陸後跳轉界面。

MainActivity.java

/**
 * 登陸主界面,模擬的demo
 * @author jan
 */
public class MainActivity extends Activity implements OnClickListener{
	
	private static final String TAG = "MainActivity";
	private EditText mLoginName;
	private EditText mPwd;
	private Button mLoginButton;
	private Button mRestButton;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mLoginName = (EditText) findViewById(R.id.login_name_et);
		mPwd = (EditText) findViewById(R.id.pwd_et);
		mLoginButton = (Button) findViewById(R.id.login);
		mRestButton = (Button) findViewById(R.id.reset);
		mLoginButton.setOnClickListener(this);
		mRestButton.setOnClickListener(this);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.login:
			login();
			break;
		case R.id.reset:
			reset();
			break;
		}
	}
	/**
	 * 登陸,沒有實際的驗證等操作,這裏就是跳轉到另一個界面
	 */
	private void login(){
		Intent intent = new Intent(MainActivity.this,ResultActivity.class);
		intent.putExtra("name", mLoginName.getText().toString());
		intent.putExtra("pwd", mPwd.getText().toString());
		startActivity(intent);
	}
	/**
	 * 重置,清除所有輸入
	 */
	private void reset(){
		mLoginName.setText("");
		mPwd.setText("");
	}
}
ResultActivity.java

public class ResultActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.result);
		Intent get = getIntent();
		String name = get==null?"":get.getStringExtra("name");
		String pwd = get == null?"":get.getStringExtra("pwd");
		((EditText)findViewById(R.id.name_et)).setText(name);
		((EditText)findViewById(R.id.pwd_et)).setText(pwd);
	}
	
}


2.創建測試項目,在package Explorer區右鍵New->點擊Progect,彈出選項選中Android:Android Test Progec-點擊Next->輸入單元測試項目名稱progect name->點擊Next->選擇被測項目(本例中的TestActivity.->finish. 

3.創建完成後,可以看看這個空的項目是什麼特別之處,看AndroidManifest.xml,原來是導入了android的測試環境

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

    <uses-sdk android:minSdkVersion="8" />

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.example.testactivity" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="android.test.runner" />
    </application>

</manifest>
4.創建我的測試類,針對MainActivity的MainActivityTest類,繼承了ActivityInstrumentationTestCase2,該類是可以單獨測試App中的某個界面。

/**
 * MainActivity的測試類
 * @author jan
 */
public class MainActivityTest extends
		ActivityInstrumentationTestCase2<MainActivity> {

	private MainActivity mActivity;
	private Instrumentation mInstrumentation;
	private EditText nameEt;
	private EditText pwdEt;
	private Button loginButton;
	private Button resetButton;

	public MainActivityTest() {
		super(MainActivity.class);
	}

	//初始設置
	@Override
	protected void setUp() throws Exception {
		super.setUp();
		Log.i("MainActivityTest", "---setUp---");
		//避免手動觸摸的情況,關閉TouchMode
		setActivityInitialTouchMode(false);
		mInstrumentation = getInstrumentation();
		//獲取被測的Activity
		mActivity = getActivity();
		//獲取這個活動界面的控件
		nameEt = (EditText) mActivity
				.findViewById(com.example.testactivity.R.id.login_name_et);
		pwdEt = (EditText) mActivity
				.findViewById(com.example.testactivity.R.id.pwd_et);
		loginButton = (Button) mActivity
				.findViewById(com.example.testactivity.R.id.login);
		resetButton = (Button) mActivity
				.findViewById(com.example.testactivity.R.id.reset);
	}
	//測試:確保每個控件都不爲空
	public void testPreCondition() {
		assertNotNull(mActivity);
		assertNotNull(nameEt);
		assertNotNull(pwdEt);
		assertNotNull(loginButton);
		assertNotNull(resetButton);
	}

	public void input() {
		//通過這個方式在UI上模擬點擊的事件
		mActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				nameEt.requestFocus();
				nameEt.performClick();
			}
		});
		//等待被測試的應用程序的主線程 與 測試用例的線程 同步,大概是這個意思吧
		mInstrumentation.waitForIdleSync();
		//模擬輸入 測試數據的鍵值
		sendKeys(KeyEvent.KEYCODE_T, KeyEvent.KEYCODE_E, KeyEvent.KEYCODE_S,
				KeyEvent.KEYCODE_T, KeyEvent.KEYCODE_N, KeyEvent.KEYCODE_A,
				KeyEvent.KEYCODE_M, KeyEvent.KEYCODE_E);
		mActivity.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				pwdEt.requestFocus();
				pwdEt.performClick();
			}
		});
		sendKeys(KeyEvent.KEYCODE_1, KeyEvent.KEYCODE_2, KeyEvent.KEYCODE_3,
				KeyEvent.KEYCODE_4, KeyEvent.KEYCODE_5);
	}

	public void testInput(){
		input();
		//測試輸入的值與預測的內容是否一致
		assertEquals("testname",nameEt.getText().toString());
		assertEquals("12345", pwdEt.getText().toString());
	}
	/**
	 * 測試登陸的功能
	 */
	public void testLogin(){
		input();
		mInstrumentation.runOnMainSync(new Runnable() {
			@Override
			public void run() {
				loginButton.requestFocus();
				loginButton.performClick();
			}
		});
	}
	/**
	 * 測試重置按鈕的功能
	 */
	public void testReset(){
		input();
		mInstrumentation.runOnMainSync(new Runnable() {
			@Override
			public void run() {
				resetButton.requestFocus();
				resetButton.performClick();
			}
		});
		assertEquals("", nameEt.getText().toString());
		assertEquals("", pwdEt.getText().toString());
	}
	
	//用於對資源的回收和釋放
	@Override
	protected void tearDown() throws Exception {
		Log.i("MainActivityTest", "---tearDown---");
		super.tearDown();
	}

}
同樣的,還可以對ResultActivity這麼做:

public class ResultActivityTest extends
		ActivityInstrumentationTestCase2<ResultActivity> {

	private ResultActivity resultActivity;
	private EditText nameEt,pwdEt;
	
	public ResultActivityTest(){
		super(ResultActivity.class);
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		//創建Intent,通過Intent傳遞用戶的登錄信息  
        Intent intent = new Intent();  
        intent.putExtra("name", "helloworld");  
        intent.putExtra("pwd", "123456");  
        //通過攜帶用戶登錄信息的intent啓動FxResultActivity  
        resultActivity = launchActivityWithIntent("com.example.testactivity", ResultActivity.class, intent);
        //獲取UI組件  
        nameEt = (EditText)resultActivity.findViewById(com.example.testactivity.R.id.name_et);
        pwdEt = (EditText)resultActivity.findViewById(com.example.testactivity.R.id.pwd_et); 
	}	
	
	public void testLoginInfo(){
		assertEquals("helloworld", nameEt.getText().toString());
		assertEquals("123456", pwdEt.getText().toString());
	}
}
5.你可以運行他了,選中要運行的ActivityTest,右鍵Run as ->Android Junit Test ,然後就看他的無手動操作的測試,方法是順序執行的,可能你會發現執行完testLogin後就不執行下去了,那是因爲他已經跳轉到另一個界面,所以測試其他的方法可以先屏蔽掉testLogin即可。


好了,這只是一個小技巧,實際中用到的並不多,只需瞭解即可,當然有興趣的可以試試看



發佈了70 篇原創文章 · 獲贊 36 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章