魯德——Android之編寫測試用例
測試是軟體工程中一個非常重要的環節,而測試用例又可以顯著地提高測試的效率和準確性。測試用例其實就是一段普通的程序代碼,通常是帶有期望的運行結果的,測試者可以根據最終的運行結果來判斷程序是否能正常工作。
我相信大多數的程序員都是不喜歡編寫測試用例的,因為這是一件很繁瑣的事情。明明運行一下程序,觀察運行結果就能知道對與錯了,為什麼還要通過代碼來進行判斷呢?確實,如果只是普通的一個小程序,編寫測試用例是有些多此一舉,但是當你正在維護一個非常龐大的工程時,你就會發現編寫測試用例是非常有必要的。
舉個例子吧,比如你確實正在維護一個很龐大的工程,裡面有許許多多數也數不清的功能。某天,你的領導要求你對其中一個功能進行修改,難度也不高,你很快就解決了,並且測試通過。但是幾天之後,突然有人發現其他功能出現了問題,最終定位出來的原因竟然就是你之前修改的那個功能所導致的!這下你可冤死了。不過千萬別以為這是天方夜譚,在大型的項目中,這種情況還是很常見的。由於項目里的很多代碼都是公用的,你為了完成一個功能而去修改某行代碼,完全有可能因此而導致另一個功能無法正常工作。
所以,當項目比較龐大的時候,一般都應該去編寫測試用例的。如果我們給項目的每一項功能都編寫了測試用例,每當修改或新增任何功能之後,就將所有的測試用例都跑一遍,只要有任何測試用例沒有通過,就說明修改或新增的這個功能影響到現有功能了,這樣就可以及早地發現問題,避免事故的出現。
1、創建測試工程
介紹了這麼多,也是時候該動手嘗試一下了,下面我們就來創建一個測試工程。在創建之前你需要知道,測試工程通常都不是獨立存在的,而是依賴於某個現有工程的,一般比較常見的做法是在現有工程下新建一個tests文件夾,測試工程就存放在這裡。
那麼我們就給剛創建的項目test創建一個測試工程吧。在Eclipse的導航欄中點擊File→New→Other,會打開一個對話框,展開Android目錄,在裡面選中Android Test Project,如圖1所示。
點擊Next後會彈出創建Android測試工程的對話框,在這裡我們可以輸入測試工程的名字,並選擇測試工程的路徑。按照慣例,我們將路徑選擇為test項目的tests文件夾下,如圖2所示。
現在點擊Finish就可以完成測試工程的創建了。觀察測試工程中AndroidManifest.xml文件的代碼,如下所示:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.example.test" />
<application android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<uses-library android:name="android.test.runner" />
application>manifest>
其中和標籤是自動生成的,表示這是一個測試工程,在標籤中還通過android:targetPackage屬性指定了測試目標的包名。
2、進行單元測試
創建好了測試工程,下面我們來對BroadcastBestPractice這個項目進行單元測試。單元測試是指對軟體中最小的功能模塊進行測試,如果軟體中的每一個單元都能通過測試,說明代碼的健壯性就已經非常好了。
test項目中有一個ActivityCollector類,主要是用於對所有的Activity進行管理的,那麼我們就來測試這個類吧。首先在testTest項目中新建一個ActivityCollectorTest類,並讓它繼承自AndroidTestCase,然後重寫setUp()和tearDown()方法,如下所示。
public class ActivityCollectorTest extends AndroidTestCase {
@Override protected void setUp() throws Exception { super.setUp();
}
@Override protected void tearDown() throws Exception { super.tearDown();
}
}
其中setUp()方法會在所有的測試用例執行之前調用,可以在這裡進行一些初始化操作。tearDown()方法會在所有的測試用例執行之後調用,可以在這裡進行一些資源釋放的操作。
那麼該如何編寫測試用例呢?其實也很簡單,只需要定義一個以test開頭的方法,測試框架就會自動調用這個方法了。然後我們在方法中可以通過斷言(assert)的形式來期望一個運行結果,再和實際的運行結果進行對比,這樣一條測試用例就完成了。測試用例覆蓋的功能越廣泛,程序出現bug的概率就會越小。
比如說ActivityCollector中的addActivity()方法是用於向集合里添加活動的,那麼我們就可以給這個方法編寫一些測試用例,代碼如下所示:
public class ActivityCollectorTest extends AndroidTestCase {
@Override protected void setUp() throws Exception { super.setUp();
} public void testAddActivity()
{
ssertEquals(0, ActivityCollector.activities.size());
MainActivity main = new MainActivity();
ActivityCollector.addActivity(main);
assertEquals(1, ActivityCollector.activities.size());
}
@Override protected void tearDown() throws Exception { super.tearDown();
}
}
可以看到,這裡我們添加了一個testAddActivity()方法,在這個方法的一開始就調用了assertEquals()方法來進行斷言,認為目前ActivityCollector中的活動個數是0。接下來new出了一個LoginActivity的實例,並調用addActivity()方法將這個活動添加到ActivityCollector中,然後再次調用assertEquals()方法進行斷言,認為目前ActivityCollector中的活動個數是1。
現在可以右擊測試工程→Run As→Android JUnit Test來運行這個測試用例,結果如圖
推薦閱讀: