1. 程式人生 > >android 單元測試脫坑

android 單元測試脫坑

說明

本文描述的是Junit4,筆者是android 兩年的搬運工,寫專案很少寫單元測試。
但有時候測一段邏輯或者網路請求需要把工程跑一遍,再操作一遍。
接觸單元測試才認識到它的強大,它能省去很多麻煩和時間。
我們雖然不是測試,也應該知道怎麼去簡單使用它來提高效率。

一、配置單元測試環境

1,筆者先說兩個遇見的問題,按照別人blog說明進行了配置,android studio 給我說 androidTestCast...等等一大堆已經過時了,看著各種各樣的測試就煩,簡單用下JUnit夠用就是了。

一言不和就上圖:

配置錯誤導致編譯不過

圖片說明:

1,在config中新增testInstrumentationRunner “android.support.test.runner.AndroidJUnitRunner”。
2,錯誤描述,大概意思是測試的api和執行的api版本不同編譯失敗,
support包下發現有個23.1.1annotations,於是重新指定這個版本就是了
:androidTestCompile ‘com.android.support:support-annotations:25.1.0’

常規正確的配置

進入正題Junit4

androidTest

建立專案的時候預設生成兩個目錄,androidTest和test。
如果你也像筆者一樣建立的時候把這兩個刪了也沒關係,新建一個包androidTest再加個包java再加路徑就是了。
這裡要說的是這裡目錄的測試執行在裝置或者模擬器,可以拿到Context和Activity。
在類前指定* @RunWith(AndroidJUnit4.class) *

package unittest.com.cannan.unittest;

import android.support.test.rule.ActivityTestRule
; import android.support.test.runner.AndroidJUnit4; import android.util.Log; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static android.support.test.espresso.Espresso.onView; import static android.support
.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; import static android.support.test.espresso.action.ViewActions.typeText; import static android.support.test.espresso.matcher.ViewMatchers.withId; @RunWith(AndroidJUnit4.class) public class MainActivityTest { private static final String STR="Cannan "; @Rule public ActivityTestRule<MainActivity> mainActivityActivityTestRule =new ActivityTestRule<>(MainActivity.class); @Test public void showMsg(){ //onView可能提示不出來導包 可以先寫onView();再使用按快捷提示 onView(withId(R.id.editText2)).perform(typeText(STR)); onView(withId(R.id.editText3)).perform(typeText(STR),closeSoftKeyboard()); onView(withId(R.id.button)).perform(click()); Log.i("TAG",getClass().getCanonicalName()+"------------"); } }

test

test目錄下的測試類一般執行與pc上,不能使用Log。
筆者主要使用這裡來測試Api或者測試獨立java類,靈活運用@before 和@after @test註解就行了,沒什麼說的。
package com.cqutprint.shundai.api;

import com.facebook.stetho.okhttp3.StethoInterceptor;
import com.google.gson.Gson;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;

import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.functions.Action1;

public class ApiManagerTest {

    private ApiServer apiServer;

    //@Before 註解方法,執行在最前面,一般做初始化動作。 
    @Before
    public void init() {
        System.out.print("--------init----------\n");
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.addNetworkInterceptor(new StethoInterceptor());
        String BASE_URI = "http://sgn5200.imwork.net:22166/shundai/";
        Retrofit.Builder retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URI)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(new Gson()));

        retrofit.client(builder.build());
        apiServer = retrofit.build().create(ApiServer.class);
    }

    @Test
    public void getInstance() throws Exception {
        Assert.assertNotNull(apiServer);
    }

    @Test
    public void getGirlData() throws Exception {
        setAction(apiServer.getGrilsRx(2));
    }

    // 測試結束後的動作
    @After
    public void end(){
        System.out.print("\n--------end----------");
    }

    private void setAction(Observable<ResponseBody> observable){
        observable.subscribe(new Action1<ResponseBody>() {
            @Override
            public void call(ResponseBody responseBody) {
                try {
                    String rs= responseBody.string();
                    System.out.println(rs);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}