qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請?jiān)L問 http://qaseven.github.io/

          Android測試驅(qū)動(dòng)開發(fā)實(shí)踐

           在Android應(yīng)用開發(fā)中,相信很少有人在堅(jiān)持先由設(shè)計(jì)人員做完整的概要設(shè)計(jì) 、詳細(xì)設(shè)計(jì),然后交給程序員進(jìn)行編碼實(shí)現(xiàn)了。通常是在有一個(gè)大體框架的情況下,就開始進(jìn)行具體編碼開發(fā)了。在這種情形下,開發(fā)速度可以有很大的提高,但是最終代碼質(zhì)量卻不可避免的降低了。如何能既保持開發(fā)速度,同時(shí)又能保證開發(fā)質(zhì)量呢?相信測試驅(qū)動(dòng)開發(fā)是一種比較可行的開發(fā)方法學(xué)。
            測試驅(qū)動(dòng)開發(fā)首先通過設(shè)計(jì)測試用例,對從用戶需求到方法接口進(jìn)行細(xì)化,在構(gòu)想這些測試用例的過程,就是站在使用者角度上來思考系統(tǒng)的過程,而傳統(tǒng)方法中設(shè)計(jì)人員通常是站在技術(shù)人員的角度來思考問題,兩者比較,顯然測試驅(qū)動(dòng)開發(fā)更有助于開發(fā)出更符合用戶需求的產(chǎn)品,同時(shí)開發(fā)出高復(fù)用性代碼。
            測試驅(qū)動(dòng)開發(fā)先寫測試,這樣就保證了充分考慮到了方法使用者需要,可以使方法更加合理。接下來進(jìn)行代碼開發(fā),以盡可能短的時(shí)間通過測試用例,在這個(gè)過程中暫時(shí)忘掉OO和設(shè)計(jì)模式吧。當(dāng)通過測試用例之后,我們再回過頭來審視我們的代碼實(shí)現(xiàn),再去除類間依賴關(guān)系,使用恰當(dāng)?shù)脑O(shè)計(jì)模式,這比在開始階段憑空想象要好得多。反復(fù)上述過程,自然可以得到質(zhì)量更高的代碼和系統(tǒng)。
            然而,在Android系統(tǒng)下,進(jìn)行測試驅(qū)動(dòng)開發(fā)又增加了額外的難度,怎樣對Activity、Provider、Service、Broadcaster等進(jìn)行單元測試,是一個(gè)必須要解決的問題,下面我們就以一個(gè)實(shí)際系統(tǒng)的開發(fā),來看一看怎么解決這一系列的問題。
            進(jìn)行測試驅(qū)動(dòng)開發(fā),首先要做的就是建立一個(gè)真正可運(yùn)行的骨架系統(tǒng),做Android下的測試驅(qū)動(dòng)開發(fā)也不例外。
            先建立一個(gè)Android工程,這里以mhcs為例,采用Eclipse向?qū)В⒃摴こ獭<僭O(shè)這個(gè)工程在用戶第一次使用時(shí),需要顯示三個(gè)介紹頁面,用戶在一張一張劃過之后,才開始使用正常功能。接下來我們就以這個(gè)功能為例,詳細(xì)描述一下在Android下怎樣進(jìn)行測試驅(qū)動(dòng)開發(fā)。
            首先,準(zhǔn)備三張介紹圖片,放入res/drawable目錄下。我們定義FlipIntroActivity類來處理用戶的劃動(dòng)操作及介紹圖片顯示。由于我們要在用戶第一次運(yùn)行時(shí)才向用戶顯示介紹頁面,因些需要保存用戶是否第一次使用系統(tǒng)的信息。我們利用Application的子類AppPreferences來管理應(yīng)用所需的所有信息。
            這時(shí)我們需要完成的功能就很清楚了,程序在第一次運(yùn)行時(shí)顯示介紹頁面,而之后的運(yùn)行中,不顯示介紹頁面。是否顯示介紹頁面,由AppPreferences類來管理。
            下面在Eclipse里建立測試工程,選擇新工程類型為Android Junit Test工程,同時(shí)選擇上面建立的工程作為被測試工程。
            好了,最小可運(yùn)行骨架系統(tǒng)已經(jīng)建立好了,下面就可以進(jìn)入正式的測試驅(qū)動(dòng)開發(fā)流程了。
            首先寫測試用例:新建類AppPreferencesTest,由于被測試類AppPreferences是Application的子類,因此AppPreferencesTest類需要繼承ApplicationTestCase
          public class AppPreferencesTest extends ApplicationTestCase<AppPreferences> {
          public AppPreferencesTest(Class<AppPreferences> applicationClass) {
          super(applicationClass);
          }
          }
            我們首先測試AppPreferences在第一次運(yùn)行時(shí),可以返回true,在AppPreferencesTest類里添加如下測試代碼:
          public void testFirstRunTrue() {
          assertTrue(prefs.isFirstRun());
          }
          private AppPreferences prefs = new AppPreferences();
            這如你所看到的,這段代碼編譯器立即使出錯(cuò)誤,不要擔(dān)心,測試驅(qū)動(dòng)開發(fā)總是從不能通過的測試用例開始的,每次努力通過一個(gè)測試用例,在通過一個(gè)個(gè)測試用例的過程中取得進(jìn)展。
            下面我們首先編寫代碼,通過這個(gè)測試用例,我們在AppPreferences類中添加如下代碼:
          public boolean isFirstRun() {
          return isFirstRun;
          }
          public void setFirstRun(boolean isFirstRun) {
          this.isFirstRun = isFirstRun;
          }
          private boolean isFirstRun = true;
            但是,如果是第二次運(yùn)行,系統(tǒng)不是還會(huì)顯示true嗎?這明顯是不正確的!一點(diǎn)兒沒錯(cuò),這段代碼確實(shí)沒有實(shí)現(xiàn)我們之前的想法,但是這段代碼卻可以通過我們的測試用例,測試驅(qū)動(dòng)開發(fā)的原則就是以盡量快的速度通過測試用例。


          好了,在測試工程中選擇AppPreferencesTest,然后選擇Android Junit Test,系統(tǒng)運(yùn)行,你會(huì)在Junit視圖中看到綠色用例通過標(biāo)記。
            下面添加一段代碼,測試當(dāng)?shù)诙芜\(yùn)行時(shí)的情況:
          public void testSecondAndMoreRun() {
          prefs.isFirstRun();
          assertFalse(prefs.isFirstRun());
          }
            運(yùn)行上述工程,結(jié)果測試用例testSecondAndMoreRun不能通過,下面我們就來處理這種情況,在生產(chǎn)工程中的AppPreferences類中添加如下代碼:
          public boolean isFirstRun() {
          boolean orgVal = isFirstRun;
          isFirstRun = false;
          return orgVal;
          }
            這時(shí)再來運(yùn)行測試工程的AppPreferencesTest類,又可以看到令我們心曠神怡的綠色通過標(biāo)志了。
            下面就剩下第一次運(yùn)行可以通過,第二次運(yùn)行不能通過。具體代碼如下所示:
            在生產(chǎn)項(xiàng)目的類AppPreferences中添加:
          @Override
          public void onCreate() {
          super.onCreate();
          }
          public void onTerminate() {
          super.onTerminate();
          }
          public boolean isFirstRun() {
          prefs = getSharedPreferences("mhcs", MODE_PRIVATE);
          boolean orgVal = isFirstRun;
          isFirstRun = false;
          Editor editor = prefs.edit();
          editor.putBoolean(PREF_IS_FIRST_RUN, false);
          editor.commit();
          return orgVal;
          }
          public void setFirstRun(boolean isFirstRun) {
          this.isFirstRun = isFirstRun;
          }
          public final static String PREF_IS_FIRST_RUN = "isFirstRun";
          private SharedPreferences prefs = null;
          private boolean isFirstRun = true;
            在測試項(xiàng)目的測試類中添加代碼:
          public void testFirstRunTrue() {
          createApplication();
          prefs = getApplication();
          Editor editor = mContext.getSharedPreferences("mhcs", 0).edit();
          editor.clear().commit();
          assertTrue(prefs.isFirstRun());
          }
          public void testSecondAndMoreRun() {
          createApplication();
          prefs = getApplication();
          assertFalse(prefs.isFirstRun());
          }
            尤其需要注意的是testFirstRunTrue方法中,先將SharedPreferences清空的處理,這樣可以模擬程序安裝后第一次運(yùn)行。
            運(yùn)行測試項(xiàng)目的測試用例,終于可以看到完整功能的綠色通過標(biāo)志了。

          posted on 2013-12-18 11:16 順其自然EVO 閱讀(331) 評論(0)  編輯  收藏 所屬分類: android

          <2013年12月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 邯郸市| 绥棱县| 和田县| 安吉县| 鄂托克旗| 通州市| 岳普湖县| 安丘市| 云龙县| 林甸县| 潮州市| 九寨沟县| 双城市| 阜宁县| 湖口县| 广德县| 荆州市| 德庆县| 日照市| 龙海市| 喀喇沁旗| 兴隆县| 黔西| 祁连县| 十堰市| 望都县| 千阳县| 项城市| 莎车县| 南阳市| 昌乐县| 云林县| 湟源县| 镇赉县| 新邵县| 定结县| 五寨县| 和林格尔县| 社会| 子长县| 丹凤县|