超乎想象的Espresso

——只有你想不到的,没有它做不到的。

espresso

阅读本文大约需要10分钟

介绍

在2013年的GTAC( Google Test Automation Conference)上,Google首次提出Espresso,见《Espresso: Fresh Start to Android UI Testing》

目前官方提供的Espresso使用文档已经相当详细,此处不再赘述。

Espresso测试是非常容易实现的,它由三部分组成:

ViewMachers:寻找用来测试的View

ViewActions:发送交互事件

ViewAssertions:检验测试结果

详情可见官网提供的参考手册:

cheat-sheet

功能

  1. 直接在主线程中运行,无需添加等待时间

  2. 支持双击

  3. 支持Web测试

  4. 支持悬浮窗测试

  5. 支持关闭软键盘

  6. clear一键清除文本

  7. 直接获取资源图标进行匹配,克服截图存在分辨率不同的问题

  8. 图表点击及图片匹配更精准

  9. DatePicker、TimePicker直接设置时间

  10. 当所要操作的元素需要滑动控件才能定位时,若为加载数据,可使用onData通过对应的Adapter快速定位并进行操作;在layout布局文件中直接定义的控件,通过perform(scrollTo())可直接定位

  11. 对同一个控件进行 连续多个操作,可以直接使用perform(scrollTo(),click())

  12. toast检查更加方便

  13. 通过集成或实现接口方式注入IdlingResources来检测异步任务

  14. 多语言脚本直接使用相同脚本,无需全部重写

  15. 与源码使用相同的元素标记,同步修改,免去使用查看元素id的复杂步骤,也避免了id改变就需要重新编写脚本的麻烦

  16. 可旋转屏幕

  17. 通过代码直接获取或改变View的任何状态

缺陷

  1. 不支持跨进程测试,可以与UiAutomator结合使用

  2. 测试中若退出应用后,测试即刻中断,无法重新打开Activity。可结合Instrumentation特性直接使用生命周期的回调函数

  3. 存在同个界面有多个id或文本相同的元素,且无法通过ondata简单定位的情况

  4. 未提供获取ondata中加载的所有数据的方法

  5. Activity与Activity之间跳转,需要时间等待

改进

ViewInteraction类添加以下方法:

atPosition(int position):存在相同元素时,可指定position使用

getView():获取指定ViewMatchers的View,可以直接获取该View的任意属性,或在UiThread中修改该View的任意属性

getViews():获取指定ViewMatchers的View列表,利用该函数可以获取存在相同元素时的指定索引的View,然后同getView()

withTimeOut(int millisecond):在指定时间内,单位毫秒,等待控件出现

withNoTimeOut():无限等待控件出现,必须确保控件会出现,否则会出现死循环

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
final int DEFAULT_WAIT_TIME = 3000;

onView(withId(R.id.text)).withTimeOut(DEFAULT_WAIT_TIME).check(matches(isDisplayed()));//等待id为text的控件加载完成

final View view = onView(withId(R.id.button)).getView();

int height = view.getHeight();

getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
view.setMinimumHeight(height +100);
}
});

ViewMatchers类添加以下方法:

withDrawable( int drawableId):根据指定图标id值获取控件

noDrawable():指定控件不包含图标

例子:

1
onView(withDrawable(R.drawable.button)).check(matches(isDisplayed()));

添加DataMatcher类:

getTitleList():可获得指定属性值的列表,用来遍历判断数据是否正确

例子:

1
2
3
4
5
6
7
DataMatcher moduleBeanMatcher = new DataMatcher(ModuleBean.class);

DataInteraction page = onData(moduleBeanMatcher).inAdapterView(getListViewMatcher());

page.atPosition(0).check(matches(isDisplayed()));

List<ModuleBean> moduleBeanList = moduleBeanMatcher.getDataList();

引用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//申明使用本地仓库
repositories{
flatDir{
dirs 'libs'
}
}

dependencies {
//工程的其他引用********************
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
}
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
compile 'javax.inject:javax.inject:1'
compile files('libs/guava-18.0.jar')
androidTestCompile(name: 'espresso', ext: 'aar')
provided files('libs/dagger-2.1-20150513.195741-5.jar')
provided files('libs/dagger-compiler-2.1-20150513.195817-5.jar')
provided files('libs/dagger-producers-2.1-20150513.195750-5.jar')
androidTestCompile 'com.android.support.test.espresso:espresso-web:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
}

本章重在介绍Espresso,具体代码请参考GitHub示例