Android測試驅動開發實踐2
在實際項目開發過程中,一般先實現核心功能,最后再做輔助性功能,這樣可以盡快驗證Idea的正確性,同時有助于讓老板、投資人或客戶看到可運行的產品,從而對產品充滿信心,加大對項目的支持。
但是對于我們這個項目而言,我們首先需要得到一個Android應用MVC的架構體系,因此我們首先來實現一些典型功能,但是可以完整體現MVC架構的功能。在此我們選擇任何應用程序在啟動時都會顯示的Splash頁面,通常這個頁面會顯示一個應用圖片,過30秒左右再顯示程序的主界面,應用在這段時間完成數據加載等準備工作。
在這里,我們采用驗收測試驅動開發的理念,即我們開發足夠功能來滿足一個驗收測試用例。這里我們選擇的一個驗收測試用例為:應用在開啟時,先顯示10秒應用圖片,然后自動進入應用首頁,也就是我們通常所看到的Splash屏幕功能。
我們首先定義SplashActivity類,代碼如下所示:
package com.bjcic.wkj; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.WindowManager; public class SplashActivity extends Activity { // 生命周期方法---開始 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //全屏 setContentView(R.layout.splash); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); appModel = (AppModel)getApplication(); appController = appModel.getAppController(); appController.postDelayed(new Runnable() { /** * 隔10秒鐘啟動主頁面 */ @Override public void run() { appController.processEvent(new AppEvent(SplashActivity.this, AppEvent.EVE_SPLASH_END, null)); } }, AppKeys.SPLASH_DURATION); // 啟動異步任務準備應用數據 } // 生命周期方法---結束 private AppController appController = null; private AppModel appModel = null; } |
這個Activity所對應的布局文件為:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@drawable/splash"> </LinearLayout> |
布局文件就是定義了一下Splash屏幕的背景圖。
這里我們引入了AppController類,是應用的控制器類。Activity中用戶的操作和系統的狀態改變都會生成相應的事件,由AppController.processEvent來進行統一處理,同時異步任務、線程等產生的需要界面更新的操作,通過向AppController發送Message來實現(因為AppController繼承了Handler類)。具體代碼如下所示:
package com.bjcic.wkj; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; public class AppController extends Handler { public AppController(AppModel appModel) { super(); this.appModel = appModel; } /** * Activity中會根據用戶的操作或系統狀態,產生對應的事件,發送給AppController進行統一處理。 * @param event */ public void processEvent(AppEvent event) { switch (event.getEventId()) { case AppEvent.EVE_SPLASH_END: // 從Splash界面顯示主界面 showMainActivity((Activity)event.getContext(), event.getParams()); break; default: break; } } /** * 異步任務、線程、后臺服務等需要更新界面時,向AppController發送消息即可 */ @Override public void handleMessage(Message msg) { super.handleMessage(msg); } /** * 關閉Splash頁面并打開應用主界面 * @param activity * @param params */ private void showMainActivity(Activity activity, Bundle params) { Log.d("wkj", "activity=" + activity + "; c=" + MainActivity.class + "!"); Intent intent = new Intent(activity, MainActivity.class); activity.startActivity(intent); activity.finish(); } private AppModel appModel = null; } |
在上面的代碼中,事件處理函數直接寫在的應用總的Controller中,其實也可以寫到具體的Controller中,為了代碼的可維護性,最好還是將事件處理寫到對應模塊的Controller中比較好。
下面就是AppEvent的定義:
package com.bjcic.wkj; import android.content.Context; import android.os.Bundle; public class AppEvent { public AppEvent(Context context, int eventId, Bundle params) { this.context = context; this.eventId = eventId; this.params = params; } public Context getContext() { return context; } public void setContext(Context context) { this.context = context; } public Bundle getParams() { return params; } public int getEventId() { return eventId; } public void setEventId(int eventId) { this.eventId = eventId; } public final static int EVE_NONE = 0; public final static int EVE_SPLASH_END = 1; // Splash界面顯示時間到期 private Context context = null; private int eventId = 0; private Bundle params = null; } |
在上面的事件定義中,事件中包含當前的Activity,事件ID和事件參數,這樣AppController就可以直接對事件進行處理了。
最后,我們在Splash頁面停留10秒,這里需要定義一個常量,我們將應用中需要用到的重要常量,統一定義到AppKeys中,如下所示:
package com.bjcic.wkj; public class AppKeys { public final static long SPLASH_DURATION = 10 * 1000; } |
好的,現在可以運行這個應用程序了,如果一切正常,應該可以看到一個Splash頁面顯示10秒鐘后,進入到程序主界面中。至此我們的第一個驗收測試用例就順利通過了。
這時,我們再回到WkjTest這個工程中,以Android Junit形式運行MainActivityTest,這時應該顯示所有測試用例全部通過。
注:大家也許注意到了,測試驅動開發是以一小步一小步的開發測試為基礎的,在實際工作中,有一半愉上的程序員喜歡先把所有代碼寫好,然后在進行調試。當然也有一部分開發人員寫一點調一點,這純屬于習慣性問題,不存在孰優孰劣的問題。但是采用測試驅動開發方法學,就要采用后面的工作方式。
因此,測試驅動開發不一定適合所有人,對于喜歡一次性先把代碼寫好,然后進行調試的人來說,讓他們接受測試驅動開發的工作方式是很困難的,這一點希望大家能夠重視起來。
相關文章:
posted on 2013-12-20 09:21 順其自然EVO 閱讀(201) 評論(0) 編輯 收藏 所屬分類: android