【Android測試】在AndroidStudio中進行單元測試
單元測試的流程
使用AndroidStudio進行單元測試時,與當前網上眾多資料進行比較。在較新版本下(當前我使用的是2.0)的studio中不需要自己進行BuildVariants的設定以及依賴JUnit包。studio會自動完成這些操作。
進行基本的單元測試的操作流程如下
圖中是我當前的目錄結構,Calculator是實現計算的實體類,首先在Calculator中進行基本的邏輯編寫,提供加減乘除四個方法。studio提供快速建立Test類的方法,對類名右擊選擇goto->test可以快速的建立或跳轉到對應類。在Create Test中提供自動生成的選項,分別是對方法的測試與測試前後進行的一些行為。
在CalculatorTest檔案中,在@Before註解中進行實體物件的建立,在@Test中分別進行方法的測試,程式碼如下:
public class CalculatorTest {
private Calculator mCal;
@Before
public void setUp() throws Exception {
mCal = new Calculator();
}
@Test
public void testSum() throws Exception {
assertEquals(6 d, mCal.sum(1d, 5d),0);
}
@Test
public void testSubstract() throws Exception {
assertEquals(2d, mCal.substract(7d, 5d),0);
}
@Test
public void testMultiply() throws Exception {
assertEquals(35d, mCal.multiply(7d, 5d),0);
}
@Test
public void testDivide () throws Exception {
assertEquals(2d, mCal.divide(10d, 5d),0);
}
}
編寫結束後執行即可得到測試結果。
assertEquals的三個引數分別為預期值,實際值,誤差範圍
將Calculator中sum方法返回值改為a-b,當測試結果與預期不一致時,顯示結果如下:描述了預期值與實際值的結果與出錯行數。
進行Instrumentation配置
androidTest資料夾是Android Instrumentation Tests的資料夾
test資料夾是Unit Tests的資料夾
首先進行gradle的配置
在defaultConfig下新增
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
在android下新增
packagingOptions {
exclude 'LICENSE.txt'
}
在dependencies下新增
androidTestCompile 'com.android.support.test:runner:0.2'
androidTestCompile 'com.android.support.test:rules:0.2'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.1'
當與v7包版本衝突時,將v7包的版本改為與test相匹配即可。
Espresso測試流程
在MainActivity中進行相關邏輯處理與程式碼編寫。
實現通過點選按鈕,TextView顯示EditText中的內容。
再建立相關測試類MainActivityInstrumentationTest,在程式碼中確定測試的類,以及測試的內容。通過 onView(withId())或onView(withText())獲取相應控制元件並進行模擬操作。相關程式碼如下:
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MainActivityInstrumentationTest {
private static final String STRING_TO_BE_TYPED = "androidTest";
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
MainActivity.class);
@Test
public void sayHello() {
//獲取editText並輸入字串
onView(withId(R.id.et)).perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard()); //line 1
//獲取button並模擬點選
// onView(withText("Say hello!")).perform(click()); //line 2
onView(withId(R.id.btn)).perform(click());
//比較應用中textView與期望字元自否匹配
String expectedText = "Hello, " + STRING_TO_BE_TYPED + "!";
onView(withId(R.id.tv)).check(matches(withText(expectedText))); //line 3
}
}
MainActivity中的邏輯:
public class MainActivity extends Activity {
private TextView tv;
private Button btn;
private EditText et;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViews();
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = et.getText().toString();
tv.setText("Hello, "+name+"!");
}
});
}
private void findViews() {
tv = (TextView) findViewById(R.id.tv);
btn = (Button) findViewById(R.id.btn);
et = (EditText) findViewById(R.id.et);
}
}
執行測試類時,在模擬器上可以看到進行了@Test中的具體步驟:
通過onView可以獲取控制元件,當需要點選的選項為ListView或Spinner這類控制元件中沒有id的選項時,可以通過onData對其進行獲取。
寫出一個介面,裡面有一個Spinner和TextView,通過點選Spinner的選項進行TextView顯示的控制。測試的流程為,先點選Spinner,通過onData獲取Spinner中的某個條目並進行模擬點選,最後驗證TextView顯示的字串是否為Spinner的選項。關於onData中的引數,通過獲取所有型別為String的選項並進行過濾。
package com.example.administrator.testspace;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onData;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
/**************************************
* Created by chenzilong on 2016/8/17.*
*************************************/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class SpinnerActivityTest {
@Rule
public ActivityTestRule<SpinnerActivity> mActivityRule = new ActivityTestRule<>(
SpinnerActivity.class);
@Test
public void getItem(){
onView(withId(R.id.spinner)).perform(click());
onData(allOf(is(instanceOf(String.class)), is("two"))).perform(click());
onView(withId(R.id.tv)).check(matches(withText("two")));
}
}
測試結果:
通過onView和onData的操作流程如圖:
因此可以獲取空間中條目位置進行模擬點選,之前的程式碼可以改為:
@Test
public void getItem(){
onView(withId(R.id.spinner)).perform(click());
onData(allOf(is(instanceOf(String.class)))).atPosition(3).perform(click());
onView(withId(R.id.tv)).check(matches(withText("four")));
}