在上一篇 Create android test project by command line and eclipse 中我們建立被測專案(TargetTestProject)以及測試專案(TestProject),並在測試專案中加入一個測試Activity的 Test Case(MainActivityTest)。
但 MainActivityTest 不算是一個真正的 Test Case,因為裡面沒有任何測試案例。
因此本篇紀錄如何加入測試案例以及測試Activity的基本模板。
加入測試案例相當簡單,因為 android test framework 使用 Junit3,而 Junit3 會將所有公開,無回傳值並以 test 開頭的方法都認為是測試案例,e.g. public void testXXX()
因此在MainActivityTest 加入以下代碼,即為一個測試案例。

    public void testPrecondition()
    {
        fail("test Precondition");
    }

testPrecondition 會是基本模板中的一部分,裡面主要是測試所有前置條件是否通過。
而 fail(“test Precondition”),代表測試程式執行到這一定會失敗並印出提示內容。
接著執行測試專案,會看到以下輸出

test:
     [echo] Running tests ...
     [exec]
     [exec] com.example.targettestproject.MainActivityTest:
     [exec] Failure in testPrecondition:
     [exec] junit.framework.AssertionFailedError: test precondition
     [exec]     at com.example.targettestproject.MainActivityTest.testPrecondition(MainActivityTest.java:36)
     [exec]     at java.lang.reflect.Method.invokeNative(Native Method)
     [exec]     at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
     [exec]     at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
     [exec]     at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
     [exec]     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:192)
     [exec]     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:177)
     [exec]     at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
     [exec]     at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1619)
     [exec]
     [exec] Test results for InstrumentationTestRunner=.F
     [exec] Time: 0.493
     [exec]
     [exec] FAILURES!!!
     [exec] Tests run: 1,  Failures: 1,  Errors: 0
     [exec]
     [exec]
BUILD SUCCESSFUL
Total time: 19 seconds

輸出的內容有點多,但重要的只有第6行 test precondition,代表測試程式目前如我們所預期的執行動作。
接著加入測試Activity的基本模板。

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
    private MainActivity mMainActivity;
    public MainActivityTest() {
        super("com.example.targettestproject", MainActivity.class);
    }
    protected void setUp() throws Exception
    {
        super.setUp();
        mMainActivity = getActivity();
    }
    protected void tearDown() throws Exception
    {
        super.tearDown();
    }
    public void testPrecondition()
    {
       assertNotNull(mMainActivity);
    }
}

第3行的 mMainActivity 即為被測專案的 MainActivity,我們需要一個欄位來保存它,因為之後需要藉由它取得其他元件。
第9行的 setUp 會在 ” 每個 ” 測試案例執行前呼叫,主要做初始化的動作,包含建立物件等等,因此可以看到mMainActivity 也在這裡初始化。
第15行的 tearDown 相對於 setUp,會在每個測試案例結束後執行,若測試案例有需要釋放資源,銷毀物件如 Service, ContentProvider 等等,請在這裡將他們指定為Null。
第20行測試前置條件 mMainActivity 不可為 Null。
以上即為測試Activity的基本模板。
若在各個函式之間加入log觀察執行順序,如下

    private static final String DEBUG_TAG = MainActivityTest.class.getSimpleName();
    protected void setUp() throws Exception
    {
        super.setUp();
        mMainActivity = getActivity();
        Log.d(DEBUG_TAG, "in setUp");
    }
    protected void tearDown() throws Exception
    {
        super.tearDown();
        Log.d(DEBUG_TAG, "in tearDown");
    }
    public void testPrecondition()
    {
        assertNotNull(mMainActivity);
        Log.d(DEBUG_TAG, "in testPrecondition");
    }

輸出如下

D/MainActivityTest( 9367): in setUp
D/MainActivityTest( 9367): in testPrecondition
D/MainActivityTest( 9367): in tearDown

可以看到 setUp 會在 testPrecondition 之前呼叫,而 tearDown 會在 testPrecondition 之後呼叫。
下一篇會在被測程式加入 UI 功能並在測試程式加入相對應的測試案例。