Android - 测试框架之 UI Testing - Espresso

Espresso适用于Android应用开发者使用,用来提高代码的可靠性。

Espresso是最新的UI Test框架, 支持UI的创建测试和用户流程测试, api非常简明, 运行也非常可靠. 很适合来写白盒测试, 可以实现对代码的细节测试.

Espresso的英文意思是浓咖啡, Let’s Go, 来喝杯Espresso吧!

快速开始

添加依赖库

Module/build.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
android {
defaultConfig {
// Testing config
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}
dependencies {
// Testing dependencies
androidTestCompile 'com.android.support:support-annotations:23.0.1'
androidTestCompile 'com.android.support.test:runner:0.4.1'
androidTestCompile 'com.android.support.test:rules:0.4.1'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
}

新建测试类

androidTest文件夹下新建一个测试类

1
2
3
4
5
6
7
8
9
10
11
@RunWith(AndroidJUnit4.class)
public class MyTestCase {
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void changeText() {
onView(withId(R.id.button)).perform(click()).check(matches(withText(R.string.finish)));
}
}

  • 使用 @RunWith(AndroidJUnit4.class) 标记一个TestCase类
  • 使用 @Rule 标记一个测试规则
  • 使用 @Test 标记一个测试函数

运行测试类

右键测试类 -> 点击 Run 即可

1
2
3
4
5
6
7
8
Installing cn.gavinliu.testingdemo.test
DEVICE SHELL COMMAND: pm install -r "/data/local/tmp/cn.gavinliu.testingdemo.test"
pkg: /data/local/tmp/cn.gavinliu.testingdemo.test
Success
Running tests
Test running startedFinish

没有任何报错说明测试通过.

可以试着吧测试代码改成, 再次点 Run , 结果就报错了.

1
onView(withId(R.id.button)).perform(click()).check(matches(withText(R.string.app_name)));

测试不通过

Espresso 详解

Espresso 代码基本范式

1
2
onView(ViewMatcher).perform(ViewAction).check(ViewAssertion);
onData(ObjectMatcher).DataOptions.perform(ViewAction).check(ViewAssertion);
  • ViewMatcher(ObjectMatcher) : 找某些东西
  • ViewAction : 做某些事情
  • ViewAssertion : 检查某些东西

View matching

Espresso.onView() ViewMatcher 可用使用一下几种方式来指定目标View:

  • View的类名
  • View的content description
  • View的ID
  • View显示的Text

例子

点击 R.id.button 按钮, 检测文字是否为Finish
1
onView(withId(R.id.button)).perform(click()).check(matches(withText(R.string.finish)));

Adapter matching

Espresso.onData() 对于AdapterView布局 内部有很多一样的View, 使用View matching就有点不太适用了, 因为onView只会载入第一个符合要求对象.

DataOptions

操作onData()返回的数据对象

  • atPosition(int) 指定某一个对象
  • onChildView(Matcher) 指定某一个子View (循环到 View matching)
  • inAdapterView(Matcher) 指定某一个AdapterView (循环到 Adapter matching)

例子

点击所有Text为Hello的对象
1
onData(allOf(is(instanceOf(String.class)), is("Hello"))).perform(click());

Espresso 类图关系

类图关系

基于Espresso的TDD开发实践

使用 TDD 的方式开发一个 Hacker News Android 客户端

Gavin Liu wechat
欢迎您扫一扫上面的二维码,订阅我的微信公众号!