1、必要性
當編寫大程序的時候,往往不是一個人完成的,而是一個團隊共同編寫程序。有的時候你修改了一段代碼,修復了自己負責的部分的bug,但是可能導致其他部分增加了新的bug。所以如果有測試用例供整個團隊在修改代碼的過程中進行調試,就可以更方便地避免這種問題。
2、創建測試工程
選擇BroadcastBestTest工程作爲調試對象。首先點擊File -> New -> Other,然後選擇Android Test Project。然後選擇放在BroadcastTest/tests目錄下:
最後選擇調試的工程爲BroadcastBestTest,整個工程就創建好了,下面看看AndroidManifest.xml:
其中<instrumentation>和<uses-library>標籤是自動生成的,表示這是一個測試工程,在<instrumentation>標籤中還通過android:targetPackage 屬性指定了測試目標的包名。
3、進行單元測試
創建好了測試工程,下面我們來對BroadcastBestPractice 這個項目進行單元測試。單元測試是指對軟件中最小的功能模塊進行測試,如果軟件中的每一個單元都能通過測試,說明代碼的健壯性就已經非常好了。
BroadcastBestPractice 項目中有一個ActivityCollector 類,主要是用於對所有的Activity進行管理的,那麼我們就來測試這個類吧。首先在BroadcastBestPracticeTest 項目中新建一個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 void testAddActivity() {
assertEquals(0, ActivityCollector.activities.size());
LoginActivity loginActivity = new LoginActivity();
ActivityCollector.addActivity(loginActivity);
assertEquals(1, ActivityCollector.activities.size());
}
可以看到,這裏我們添加了一個testAddActivity()方法,在這個方法的一開始就調用了assertEquals()方法來進行斷言,認爲目前ActivityCollector 中的活動個數是0。接下來new 出了一個LoginActivity 的實例,並調用addActivity()方法將這個活動添加到ActivityCollector中,然後再次調用assertEquals()方法進行斷言,認爲目前ActivityCollector 中的活動個數是1。
現在可以右擊測試工程→Run As→Android JUnit Test 來運行這個測試用例,結果如下:
不過剛剛那個測試用例只是覆蓋了很小的情況而已,我們添加下面的代碼,再進行測試:
public void testAddActivity() {
assertEquals(0, ActivityCollector.activities.size());
LoginActivity loginActivity = new LoginActivity();
ActivityCollector.addActivity(loginActivity);
assertEquals(1, ActivityCollector.activities.size());
ActivityCollector.addActivity(loginActivity);
assertEquals(1, ActivityCollector.activities.size());
}
這一段代碼的意思是,再一次添加LoginActivity,由於之前已經添加過了,所以我們希望的結果是總的Activity數不變。測試結果如下:
這也說明了ActivityCollector的代碼不夠健壯,需要修改,如下:
// BroadcastBestTest - ActivityCollector.java
public static void addActivity(Activity activity) {
if (!activities.contains(activity)) {
activities.add(activity);
}
}
代碼調試過程也就是如此:增加更多的測試用例,如果發現了錯誤,就修改代碼,讓工程更加健壯。