Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Espresso Test UI

Android Espresso Test UI

編輯:關於Android編程

ps:Espresso英文文檔,本人翻譯水平有限,可能存在不足

Espresso的重要組成部分:

 1.Espresso:通過onView()和onData()與view交互的進入點,它的api不依賴任何view

 2.ViewMatchers:  實現了Matcher的集合對象。通過onView()來定位當前的view 

 3.ViewActions:   具備操作方法(例如點擊操作)的集合對象,它裡面的操作可以通過   
                  ViewInteraction.perform()來實現 

 4.ViewAssertions   用它可以斷言,查看當前view的狀態 ,ViewInteraction.check() 會執行它 

來張Espresso的小抄:

這裡寫圖片描述

案例:

onView(withId(R.id.main_view)).perform(click()).check(matches(isDisplayed())); 

 分析:withId()通過id獲取到ViewMatcher, 
      click()是一個viewAction(即操作), 
      matches()是一個ViewAssertions  

Espresso的使用步驟:

步驟(一):加載view

1.普通的view用onView()加載視圖:

1.1:R.id.xx是唯一的:   onView(withId(R.id.main_view))

1.2:存在view的id是不唯一:若是通過以上方法會報錯,com.google.android.apps.common.testing.ui.espresso.AmbiguousViewMatcherException

    解決方式:縮小范圍,通過查看所要找到的view屬性,采用多個屬性來查找

    案例:若是兩個edittext中的id相同,text內容不同,現在要獲取text內容為"Hello!":

         //通過id,text屬性來確定所要查找的edittextview:
          onView(allOf(withId(R.id.my_view), withText("Hello!"))) 

2.AdapterView類型(例如gridview,listview,spinner)中的itemView:要通過onData()加載視圖

特殊情況: 為了解決view中R.id問題(可能不存在,不唯一)的問題,獲取view視圖可以通過自定義(或者已經存在)的ViewMatchers  

步驟(二):執行action

在view中執行一個操作:
在匹配好指定view(即onView()或者onData())後,可以通過perform()來執行ViewAction

 案例之view的點擊:        onView(withId(R.id.main_view)).perform(click())

 案例之view執行多個操作:  onView(...).perform(typeText("Hello"), click());

 案例之ScrollView中的view執行:onView(...).perform(scrollTo(), click());
      理解:執行click()隨著sroolrto() ,確保執行操作在其他操作之前  

步驟(三):檢查view是否包含某種assertion

當前的view可以通過check()執行Assertions 。
通常通過matches()使用 assertion,matches()是通過 ViewMatcher來斷言當前view的狀態 

案例1:檢查view是否包含“Hello”內容

         onView(...).check(matches(withText("Hello!")));

案例2:若是view沒有明確displayed的情況下,不能將assertions放到onView()中,要將檢查放到檢查代碼塊中:

   // view的disPlay是未知情況下,assertions(斷言)view的內容是否是“Hello!”,以下代碼是不好的 

   onView(allOf(withId(...), withText("Hello!"))).check(matches(isDisplayed()));

   若是已經明確view已經顯示,這代碼是好的。

注意點:在view不顯示或者view不在當前視圖中這兩種情況下,使用assertions情況

使用IDE開始編寫:

(一)eclipse中Espresso的使用:

配置Espresso, 通過添加以下靜態jar:

這裡寫圖片描述

github上包含Android Studio和eclipse的對應項目 
(下載全部案例後,使用eclipse的,選擇BasicSampleBundled):

eclipse的案例:
https://github.com/googlesamples/android-testing/tree/master/ui/espresso/BasicSampleBundled

(二)Android Studio中Espresso的使用:

第一步:添加 Android Support Repository,(已經添加的,這步省略)

這裡寫圖片描述 <喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxzdHJvbmc+tdq2/rK9o7rU2kdyaWRsZdbQZGVwZW5kZW5jaWVze33M7bzTuPfX1NDox/O1xGphcjo8L3N0cm9uZz48L2NvZGU+PC9jb2RlPjwvY29kZT48L2NvZGU+PC9jb2RlPjwvY29kZT48L2NvZGU+PC9wPg0KPHByZSBjbGFzcz0="brush:java;"> //Android JUnit Runner androidTestCompile 'com.android.support.test:runner:0.5' // JUnit4 Rules androidTestCompile 'com.android.support.test:rules:0.5' // Espresso core androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' //測試DatePicker, RecyclerView, Drawer actions, Accessibility checks, CountingIdlingResource所需 androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.2' //測試WebView所需 androidTestCompile 'com.android.support.test.espresso:espresso-web:2.2.2' //測速異步線程所需 androidTestCompile 'com.android.support.test.espresso:espresso-idling-resource:2.2.2'

最後別忘記,sync Now

第三步:創建測試包的路徑,切換到project視圖下,找到對應的項目,在src下創建一個文件,命名為androidTest/java,然後在anroidTest/java路徑下創建一個包,填入項目的包名(已經存在對應項目的android test包,省略這步)

這裡寫圖片描述

第四步:在xxx.xxx.xx(androidStudio)下創建對應的測試類,按照Espresso使用方式,編寫測試代碼

這裡寫圖片描述

第五步:創建test configuration: Edit Configurations–> +–>Android Tests configuration–>選擇module和添加AndroidJUnitRunner ,name 自己定義,module 選擇要測試的項目
這裡寫圖片描述

最後一步:運行測試項目

這裡寫圖片描述

測試案例:Button點擊和ListView的item點擊測試:

在配置Espresso的jar你會發現一些問題:

Error:Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app (23.3.0) and test app (23.1.1) differ.
See http://g.co/androidstudio/app-test-app-conflict for details. 
這是兩個注解包沖突了

解決方式:采用你當前項目中com.android.support:support-annotations(個人這邊是23.3.0版)

gradle中jar依賴:

dependencies {

  testCompile 'junit:junit:4.12'

  compile 'com.android.support:appcompat-v7:23.3.0'
  //添加注解,包含test
  compile 'com.android.support:support-annotations:23.3.0'

  //解決沖突
   androidTestCompile  'com.android.support:support-annotations:23.3.0' 

  // Android JUnit Runner
   androidTestCompile 'com.android.support.test:runner:0.5' 

   // JUnit4 Rules
   androidTestCompile 'com.android.support.test:rules:0.5'

    // Espresso core
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' 

   }

Button所在的xml:




    
    

myadapter_item(listView中item)的xml:



MainActivity.java的代碼:

public class MainActivity extends AppCompatActivity {
   private ListView listView;;
    private List  list;
    private  TextView showChangge_tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
         listView=(ListView) this.findViewById(R.id.main_list);
        list=new ArrayList<>();
        for (int i=1;i<6;++i){
            list.add(String.valueOf(i));
        }
         listView.setAdapter(new MyAdapter());
        showChangge_tv= (TextView)     this.findViewById(R.id.main_change);
    }

    public void changContent(View v){
        showToas("onClick");
    }
    public Toast  toast;
    public void showToas(String content){
        if(toast!=null){
            toast.cancel();
        }
        toast=Toast.makeText(getApplicationContext(),content,Toast.LENGTH_SHORT);
        toast.show();
    }
    private  class MyAdapter extends BaseAdapter implements View.OnClickListener{
        @Override
        public int getCount() {
            return list.size();
        }
        @Override
        public Object getItem(int position) {
            return list.get(position);
        }
        @Override
        public long getItemId(int position) {
            return position;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder  viewHolder;
            if(convertView==null){
                viewHolder=new ViewHolder();
                convertView=View.inflate(MainActivity.this,R.layout.myadaper_item,null);
                viewHolder.textview=(TextView) convertView.findViewById(R.id.myadapter_item);
                convertView.setTag(viewHolder);
            }else{
                viewHolder=(ViewHolder) convertView.getTag();
            }
            viewHolder.textview.setText(list.get(position));
            viewHolder.textview.setOnClickListener(this);
            return convertView;
        }

        @Override
        public void onClick(View v) {
           showChangge_tv.setText(((TextView)v).getText());
        }
    }
    static   class  ViewHolder{
        TextView  textview;
    }

}

MainActivity對應測試類中代碼(重要點):

注意點:@xx這些注解不能少

package com.szejq.testdemo;

import android.support.test.espresso.Espresso;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.ViewInteraction;
import android.support.test.espresso.action.ViewActions;
import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;

import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
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;

/**
 * Created by Administrator on 2016/7/19.
 */

@RunWith(AndroidJUnit4.class) 

@LargeTest 

public class MainActivityTest {

    @Rule
    public ActivityTestRule  activityActivityTestRule 
                =new ActivityTestRule(MainActivity.class); 

    @Test
    public void changContentTest(){
           Matcher  matcher= ViewMatchers.withId(R.id.main_change); 

           //獲取R.id.main_change為id的view
           ViewInteraction  viewInteraction= Espresso.onView(matcher); 

           ViewAction  viewAction= ViewActions.click();

           viewInteraction.perform(viewAction);//點擊事件

          // 簡寫方式:onView(withId(R.id.main_change)).perform(click());
    }

    @Test
    public void testAdapterView(){

        //listView中內容為“2”的item點擊( listviwe中數據類型String,所對應的值為“2” )
       onData(Matchers.allOf(             
                Matchers.is(Matchers.instanceOf(String.class)),Matchers.is("2")  
               ) ).perform(click());

       //檢查上一步點擊事件,有沒有執行成功
         onView(withId(R.id.main_change)).check(matches(withText("2")));

    }

}

運行結果:

這裡寫圖片描述

基礎Espresso 已經ok,長征路漫漫,還有高級Espresso方式測試,待續中!

stackOverFlow上關於Espresso:
http://stackoverflow.com/questions/tagged/android-testing

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved