編輯:關於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.使用SQL Helper創建數據庫2.數據的增刪查改(PRDU:Put、Read、Delete、Update)背景知識:上篇文章學習了android保存文件,
微信名字用了一段時間就想換一個,換個新鮮,微信名字怎麼改?微信名字如何加表情?下面我們就一起來瞧一瞧吧!微信名字怎麼改1.首先在手機上面登錄到自己的微信賬號
初次用到回調是在Fragment和Activity之間進行通信的時候,當時感覺很難理解,但又覺得這個方法使用起來很方便,所以對它進行仔細的研究。發現回調不僅僅是實現功能那
接下來的幾篇博客將通過小Demo來測試下事件分發機制,進而能更好的理解源碼,至於源碼的分析,網上有很多帖子了,大家可以自行查看啦!注意本篇博客是默認在你理解了ViewGr