天天看點

Android 中的單元測試

單元測試其實分為兩種:一種為純java代碼測試,一般位于

test

包下;另一種為UI測試,一般位于

androiTest

包下。

本篇用到的單元測試架構主要有:

Junit,Mockito,Robolectric,Espresso

一、Junit

詳細資料請參考

1、添加依賴

dependencies {
    testCompile "junit:junit:4.12"
}
           

2、建立test檔案夾

app
    src
        main
            java
                com.woaikakashen
                    java代碼

        test
            java
                com.woaika.kashen
                    測試代碼
           

3、生成對應的test類

java被測試類:Student.class
test測試類:StudentTest.class
           

生成方式:

通過AndroidStudio建立,選中Student.class 點選右鍵,選擇

GoTo--->Test

來快速建立單元測試方法

運作:選中測試類中的方法右鍵

Run

方法名。

二、Mockito

詳細資料請參考資料1

詳細資料請參考資料2

1、介紹

用來為提供函數傳回結果的模拟(mock)及對函數調用過程的驗證。
           
關鍵詞

mock

: 針對真實的類或者對象,建立一個模拟(代理)的對象。

stub

: 針對一個類或者對象的方法,進行模拟調用及輸出。

2、添加依賴

dependencies {
   testCompile "org.mockito:mockito-core:2.11.0"
}
           

3、加載方式

方法一:

@Test
    public void testIsNotNull(){
        Person mPerson = mock(Person.class); //<--使用mock方法

        assertNotNull(mPerson);
    }
           

方法二:

@Mock //<--使用@Mock注解
    Person mPerson;

    @Before
    public void setup(){
        MockitoAnnotations.initMocks(this); //<--初始化
    }
           

4、常用文法

1.  打樁方法
2.  驗證方法
3.  參數比對器
4.  其他方法
           

三、Robolectric

詳細資料請參考

1、介紹

利用Android SDK和資源來編寫測試用例,并将所有的測試用例運作在java虛拟機内。不需要使用模拟器或真機來測試。

2、添加依賴

dependencies {
    testCompile "junit:junit:4.12"
    testCompile "org.robolectric:robolectric:3.0"
}
           

3、注解配置TestRunner

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk = )
public class SampleActivityTest {

}
           

4、常用文法

四、Espresso

詳細資料請參考資料1

詳細資料請參考資料2

Espresso需要依賴Android裝置.這将導緻我們将花費更多時間在編譯apk和AndroidTest apk的安裝上

4.1、添加依賴

androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
}
           

4.2、設定測試執行器

這個運作器是基于

InstrumentationTestRunner

GoogleInstrumentationTestRunner

,運作JUnit3和JUnit4來測試你的Android應用程式。
defaultConfig {
        ...
        testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
    }
           

4.3、建立androidTest檔案夾

app
    src
        main
            java
                com.woaikakashen
                    java代碼
        androidTest
            java
               com.woaikakashen
                    UI測試代碼
        test
            java
                com.woaika.kashen
                    純測試代碼
           

4.4、常用注解

@Rule:
public ActivityTestRule mActivityRule = new ActivityTestRule<>(
            MainActivity.class);
           
定義一個測試規則,構造函數參數指定一個需要被測試的頁面。當打開app會打開對應的頁面執行所定義的測試用例。
           
@Test:
用來定義一個測試用例
           

4.5、常用文法

1、通路UI元素

onView()

方法來通路UI元素,

withId()

進行id通路,使用

withText()

進行文本比對,然後在執行相應的動作,最後在驗證

eg:

//驗證id為tvLoanBig的text内容是否為極速大額貸
onView(withId(R.id.tvLoanBig)).check(matches(withText("極速大額貸")));
           
2、AdapterView

onData

方法來擷取

DataInteraction

對象,然後在來通路目标元素。Espresso處理加載目标元素到目前層次結構。
3、執行動作
調用

ViewInteraction.perform()

DataInteraction.perform()

。可以指定一個或者多個動作,Espresso會按照指定的順序,依次發送動作事件,這些動作是線程安全的.

ViewActions

可以提供一些列常用的方法,我們可以利用寫方法來操作UI元素。

  • ViewActions.click(): 點選事件
  • ViewActions.typeText(): 輸入指定的文字内容
  • ViewActions.scrollTo(): 滑動
  • ViewActions.pressKey(): 按下按鍵
  • ViewActions.clearText(): 清空文本
4、校驗結果
調用

ViewInteraction.check()

DataInteraction.check()

方法,可以判斷UI元素的狀态,如果斷言失敗,會抛出

AssertionFailedError

異常。

比如:

-

doesNotExist

: 斷言某一個view不存在

-

matches

: 斷言某個view存在,且符合一列的比對

-

selectedDescendentsMatch

:斷言指定的子元素存在,且他們的狀态符合一些列的比對

4.6、Espresso 自動化測試- RecyclerView

從測試的角度上來看

RecyclerView

不是一個

AdapterView

,這意味着你不能使用

onData()

去跟你的

list items

互動。
1、添加對應的庫
dependencies {
    // ...
   androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.0');
}
           

但是這樣子的話。gradle就會出現報錯了,出現一些依賴關系的沖突,是以我們需要去除一些重複的依賴關系。

dependencies {
    // ...

    androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.0') {
        exclude group: 'com.android.support', module: 'appcompat'
        exclude group: 'com.android.support', module: 'support-v4'
        exclude module: 'recyclerview-v7'
    }
}
           
2、常用文法

主要用到RecyclerViewActions類

2.1

actionOnItemAtPosition

//點選position為的item
onView(withId(R.id.rvLoanAll)).perform(RecyclerViewActions.actionOnItemAtPosition(, click()));
           

2.2

actionOnItem

//點選帶有 "百度有錢花" 字元串的item
onView(withId(R.id.rvLoanAll)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText("百度有錢花")), click()));
           

hasDescendant

指代的是對應的item的後代中有包含對應文本的内容的.不過使用這個需要小心 因為很有可能會出現兩個同樣内容的

2.3

scrollToPosition

//滾動到position為的位置
onView(withId(R.id.rvLoanAll)).perform(RecyclerViewActions.scrollToPosition());
           

4.7、Espresso 自動化測試- 異步代碼測試

由于成本過高,需要大量代碼,而且需要實作

idlingResource

接口,請查閱:

詳細請參考資料

//Espresso的IdlingResource異步接口依賴:
compile('com.android.support.test.espresso:espresso-idling-resource:3.0.1') {
        exclude module: 'support-annotations'
    }
androidTestCompile('com.android.support.test.espresso:espresso-idling-resource:3.0.1') {
        exclude module: 'support-annotations'
}
           

繼續閱讀