單元測試其實分爲兩種:一種爲純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、介紹
用來爲提供函數返回結果的模擬(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 = 21)
public class SampleActivityTest {
}
4、常用語法
四、Espresso
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爲5的item
onView(withId(R.id.rvLoanAll)).perform(RecyclerViewActions.actionOnItemAtPosition(5, click()));
2.2 actionOnItem
//點擊帶有 "百度有錢花" 字符串的item
onView(withId(R.id.rvLoanAll)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText("百度有錢花")), click()));
hasDescendant
指代的是對應的item的後代中有包含對應文本的內容的.不過使用這個需要小心 因爲很有可能會出現兩個同樣內容的
2.3 scrollToPosition
//滾動到position爲5的位置
onView(withId(R.id.rvLoanAll)).perform(RecyclerViewActions.scrollToPosition(5));
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'
}