1. 程式人生 > >【Android測試】在AndroidStudio中進行單元測試

【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")));
    }