如何使用ServiceTestCase進行Android的Service類型API測試

ServiceTestCase 繼承於繼承了Junit 框架中的TestCase的AndroidTestCase類。該類中包含有測試應用的許可,控制被測試的應用和Service 等大量方法。同時也提供了模擬的應用(Applcation)和上下文(Context)方便我們可以使Service 獨立於其應用進行測試。

    Service TestCase.setUp()方法在每個測試用例調用之前執行,該方法執行的時候配置測試數據通過複製並獲得當前系統提供的Context.  你可以通過getSystemContext()取得系統的當前Context。如果你重寫setUp()方法的話,第一條語句應該是super.setUp()。setApplication(Application)方法和setContext(Context)方法允許你在Service啓動之前設置模擬的Context和模擬的Application,如果不做設定,將自動爲測試指定MockApplication和MockContext。在調用startService()或者bindService()時,ServiceTestcase會自動初始化測試環境。因此,如果需要設定特定的測試環境,必須要在啓動被測Service之前創建需要模擬的對象等等。

    需要注意的是ServiceTestCase .bindService()方法和Service.bindService()方法的參數不同的:ServiceTestCase.bindService() 方法只需要提供Intent對象,而Service.bindService()還需要指定ServiceConnection和flag。而且ServiceTestCase.bindService()方法返回一個IBinder對象的子類,而Service.bindService ()返回的是布爾值。

    在每條測試用例運行結束後,teardown()方法會按照Service的生命週期進行回收。比如,通過bindService()方法啓動Service的情況下,teardown()方法會自動依次調用該Service的onUnbind()方法和onDestroy()方法。

    ServiceTestCase默認會執行testAndroidTestCaseSetupProperly()方法。用於驗證該測試類是否在運行其他測試用例之前成功地設置了上下文。

    下面以SAF的Security組件的API測試爲例,描述測試整個過程:
    首先Security組件對外提供的API是以AIDL方式暴露的兩個方法
int getAgentVersionCode()
String exec(String[] args, String directory, boolean noResult, boolean isSync)

    因此需要使用ServiceTestCase的bindService()方法來進行測試。

    首先新建測試工程,修改AndroidManifest.xml
<application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="android.test.runner" >
        </uses-library>
    </application>

    <instrumentation
        android:name=".TestRunner"
        android:targetPackage="saf.cmcc.security.agent" >
</instrumentation>
    指定被測應用包名,指定TestRunner,聲明使用android.test.runner庫

    新建TestRunner類
public class TestRunner extends InstrumentationTestRunner {
public TestSuite getAllTests() {
InstrumentationTestSuite suite = new InstrumentationTestSuite(this);
suite.addTestSuite(ApiTest.class);
return suite;
}
}

    新建測試類ApiTest
public class ApiTest extends ServiceTestCase<SecurityService> {

public ApiTest() {
super(SecurityService.class);
}

protected void setUp() throws Exception {
Log.e(getName(), "setUp...");
super.setUp();
}

protected void teardown() throws Exception {
Log.e(getName(), "tearDown...");
super.tearDown();
}

/**
 * Test bind service
 */
public void testBindable() {
Intent startIntent = new Intent();
startIntent.setClass(getSystemContext(), SecurityService.class);
IBinder service = bindService(startIntent);
assertEquals(true, service.isBinderAlive());
}

/**
 * Test getAgentVersionCode
 */
public void testGetAgentVersionCode() {
Intent startIntent = new Intent();
startIntent.setClass(getSystemContext(), SecurityService.class);
IBinder service = bindService(startIntent);
if (service.isBinderAlive()) {
SecurityAgent securityAgent = SecurityAgent.Stub
.asInterface(service);
int versionCode = 0;
try {
versionCode = securityAgent.getAgentVersionCode();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
assertEquals(2, versionCode);
}
}
}
使用與被測應用相同簽名編譯安裝測試apk,即可運行測試了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章