標籤:android testcase
有種情況,我們開發人員可能要對已經完成的應用做維護,其中某個介面可能存在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;@Overrideprotected 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);}@Overrideprotected void onDestroy() {super.onDestroy();}@Overridepublic 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 {@Overrideprotected 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 extendsActivityInstrumentationTestCase2<MainActivity> {private MainActivity mActivity;private Instrumentation mInstrumentation;private EditText nameEt;private EditText pwdEt;private Button loginButton;private Button resetButton;public MainActivityTest() {super(MainActivity.class);}//初始設定@Overrideprotected void setUp() throws Exception {super.setUp();Log.i("MainActivityTest", "---setUp---");//避免手動觸摸的情況,關閉TouchModesetActivityInitialTouchMode(false);mInstrumentation = getInstrumentation();//擷取被測的ActivitymActivity = 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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void run() {loginButton.requestFocus();loginButton.performClick();}});}/** * 測試重設按鈕的功能 */public void testReset(){input();mInstrumentation.runOnMainSync(new Runnable() {@Overridepublic void run() {resetButton.requestFocus();resetButton.performClick();}});assertEquals("", nameEt.getText().toString());assertEquals("", pwdEt.getText().toString());}//用於對資源的回收和釋放@Overrideprotected void tearDown() throws Exception {Log.i("MainActivityTest", "---tearDown---");super.tearDown();}}同樣的,還可以對ResultActivity這麼做:
public class ResultActivityTest extendsActivityInstrumentationTestCase2<ResultActivity> {private ResultActivity resultActivity;private EditText nameEt,pwdEt;public ResultActivityTest(){super(ResultActivity.class);}@Overrideprotected 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即可。
好了,這隻是一個小技巧,實際中用到的並不多,只需瞭解即可,當然有興趣的可以試試看
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
[Android初級]android單元測試之Activity單獨測試