2016年4月11日
[TOC]
1、環(huán)境搭建(版本3.0)
Android單元測試需要JUnit框架的支持斤葱,Robolectric只是提供了Android代碼的運(yùn)行環(huán)境,測試還是需要junit來實(shí)現(xiàn)。配置如下:
testCompile 'junit:junit:4.10'
testCompile 'org.robolectric:robolectric:3.0'
然后在Build Variants中的Test Artifact改為Unit Tests
弹惦。
![a-1-1.png-9.4kB](http://static.zybuluo.com/liucloo/y1oj9ns06kssrhvmuh9x881e/a-1-1.png)
在Android Studio2.0正式版中沒有這個(gè)選項(xiàng),直至忽略掉悄但。
2棠隐、第一次嘗試
在Android studio下面有Test包,新建測試類TestDemoTest
.
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class,
sdk = 21,
manifest = "src/main/AndroidManifest.xml",
packageName = "cn.liucl.andoridunittestdemo",
resourceDir = "res")
public class TestDemoTest {
public static final String TAG = TestDemoTest.class.getSimpleName();
private MainActivity mainActivity;
@Before
public void beforeTest() throws Exception {
System.out.println("before");
}
@Test
public void Testing() throws Exception {
System.out.println("Testing()");
}
}
第1行代碼檐嚣,使用注解的方式引入robolectric助泽。然后看這個(gè)類的兩個(gè)方法,使用before
注解的方法嚎京,表示在單元測試之前執(zhí)行嗡贺,可用于獲取Activity或資源文件等;而Test
注解的方法表示就是這個(gè)測試case鞍帝。執(zhí)行之后诫睬,你會(huì)發(fā)現(xiàn)Robolectric cant found resource and AndroidManifest.xml
這個(gè)錯(cuò)誤。這是robolectric沒有正確加載manifest文件帕涌。其實(shí)摄凡,Resources也沒有被加載。這樣就有這個(gè)類的第二個(gè)注解蚓曼,也就是Config亲澡。在Config里面可以指定SDK版本,資源文件以及清單文件等信息纫版。具體信息可以看他的注解谷扣。
補(bǔ)充:如果還是找不到資源,嘗試把AndroidManifest中Application的Theme改成android:theme="@style/Theme.AppCompat"
注意,第一次運(yùn)行需要下載sdk需要的組件会涎,可能需要一段時(shí)間裹匙。如果下載失敗,自備梯子末秃。
![a-1-2.png-63.2kB](http://static.zybuluo.com/liucloo/wzibfz389rbtvt8g850ligu0/a-1-2.png)
圖為正在下載概页。
3、帶上Activity
Robolectric可以創(chuàng)建Activity练慕,可以測試執(zhí)行點(diǎn)擊事件惰匙,可以測試生命周期等。
1铃将、創(chuàng)建一個(gè)Activity
Robolectric
提供對(duì)Activity的操作方法项鬼,我們獲取一個(gè)Activity只需要Robolectric.setupActivity(MainActivity.class);
就可以了。
@Before
public void beforeTest() throws Exception {
System.out.println("before");
mainActivity = Robolectric.setupActivity(MainActivity.class);
}
@Test
public void Testing() throws Exception {
Assert.assertNotNull(mainActivity); //斷言是否不為空
System.out.println("Testing()");
}
下面是Robolectric的方法:
![a-1-3.png-50.4kB](http://static.zybuluo.com/liucloo/d1h2nziu3k3ejk1hesij6dvr/a-1-3.png)
上面的buildActivity和setupActivity都可以創(chuàng)建Activity劲阎,他們的不同之處在于绘盟,setupActivity直接到Activity生命周期的運(yùn)行階段,而buildActivity只是獲取對(duì)象
public static <T extends Activity> ActivityController<T> buildActivity(Class<T> activityClass) {
return ActivityController.of(shadowsAdapter, activityClass);
}
public static <T extends Activity> T setupActivity(Class<T> activityClass) {
return ActivityController.of(shadowsAdapter, activityClass).setup().get();
}
public ActivityController<T> setup() {
return create().start().postCreate(null).resume().visible();
}
2悯仙、生命周期
ActivityController提供對(duì)Activity生命周期操作的一系列方法:(相同的龄毡,Service也是這樣)
![a-1-4.png-62.5kB](http://static.zybuluo.com/liucloo/fysntx4wkk4u127ei3m0viz1/a-1-4.png)
3、測試點(diǎn)擊
Robolectric支持點(diǎn)擊操作锡垄,首先確保Activity執(zhí)行到相應(yīng)的生命周期沦零。在MainActivity編寫好邏輯。
MainActivity
button = (Button) findViewById(R.id.test1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("Success");
}
});
TestDemoTest
@Before
public void beforeTest() throws Exception {
Log.i(TAG, "beforeTest()");
mainActivity = Robolectric.buildActivity(MainActivity.class).setup().get();//注意生命周期
button = (Button) mainActivity.findViewById(R.id.test1);
}
@Test
public void btn1(){
button.performClick();
}
在Robolectric中打Log請(qǐng)使用**System.out**货岭。Android的Log工具只有在使用Adb時(shí)候才有效路操。
4、斷言
Robolectric不提供類似Junit的assert方法來測試程序千贯。所以還是需要使用Junit的assert來測試屯仗。
assertNotNull(); //判斷對(duì)象是否不為空
assertNull();
assertEquals(); //判斷實(shí)際值和期望值是否“相同”
assertTrue(); //判斷布爾值是否為true
assertFalse();
assertNotSame();
assertSame(); //判斷實(shí)際值和期望值是否為同一個(gè)對(duì)象
5、在項(xiàng)目中使用
實(shí)際項(xiàng)目中丈牢,單元測試對(duì)象與頁面是一對(duì)一的祭钉,并不建議跨頁面,這樣的單元測試藕合度太大己沛,維護(hù)困難慌核。單元測試需要找到頁面的入口,分析項(xiàng)目頁面中的元素申尼、業(yè)務(wù)邏輯垮卓,這里的邏輯不僅僅包括界面元素的展示以及控件組件的行為,還包括代碼的處理邏輯师幕。然后可以創(chuàng)建單元測試case列表(列表用于紀(jì)錄項(xiàng)目中單元測試的范圍粟按,便于單元測試的管理以及新人了解業(yè)務(wù)流程)诬滩,列表中記錄單元測試對(duì)象的頁面,對(duì)象中的case邏輯以及名稱等灭将。工程師可以根據(jù)這個(gè)列表開始寫單元測試代碼疼鸟。
單元測試是工程師代碼級(jí)別的質(zhì)量保證工程,上述流程并不能完全覆蓋重要的業(yè)務(wù)邏輯以及邊界條件庙曙,因此空镜,需要寫完后,看覆蓋率捌朴,找出單元測試中沒有覆蓋到的函數(shù)分支條件等吴攒,然后繼續(xù)補(bǔ)充單元測試case列表,并在單元測試工程代碼中補(bǔ)上case砂蔽。
直到規(guī)劃的頁面中所有邏輯的重要分支洼怔、邊界條件都被覆蓋,該項(xiàng)目的單元測試結(jié)束左驾。
![a-1-5.jpg-169.5kB](http://static.zybuluo.com/liucloo/ajk422f8r2h0pc1q8oqq5taj/a-1-5.jpg)