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方式暴露的两个方法
intgetAgentVersionCode()
String exec(String[] args, String directory,booleannoResult,booleanisSync)
因此需要使用ServiceTestCase的bindService()方法来进行测试。
首先新建测试工程,修改AndroidManifest.xml
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<uses-libraryandroid:name="android.test.runner">
</uses-library>
</application>
<instrumentation
android:name=".TestRunner"
android:targetPackage="saf.cmcc.security.agent">
</instrumentation>
指定被测应用包名,指定TestRunner,声明使用android.test.runner库。
新建TestRunner类
publicclassTestRunnerextendsInstrumentationTestRunner {
@Override
publicTestSuite getAllTests() {
InstrumentationTestSuite suite =newInstrumentationTestSuite(this);
suite.addTestSuite(ApiTest.class);
returnsuite;
}
}