本篇详细介绍了Espresso的使用方式.

Espresso 测试代码位置和静态导入

Espresso 测试代码必须放在 app/src/androidTest 目录下.

为了简化 Espresso API 的使用, 强烈建议使用以下静态导入. 可以允许在没有类前缀的前提下访问这些静态方法.

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.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;

ViewMatcher 的使用

查找一个 View, 需要使用 onView() 方法和视图匹配器(view matcher)来选择正确的 View. 如果你使用的是 AdapterView, 需要使用 onData() 方法而不是 onView()方法. onView() 返回的是一个 ViewInteraction 类型的对象, onData() 返回的是一个 DataInteraction 类型的对象.

表1 中介绍了可用的匹配器.

表 1 Espresso 匹配器

执行操作(perform action)

ViewInteraction 和 DataInteraction 可以通过 perform 方法和 ViewActions 类型的对象指定某种操作. ViewActions 类为最常见的操作了提供了相应的辅助方法. 像:

  • ViewActions.click()
  • ViewActions.typeText()
  • ViewActions.pressKey()
  • ViewActions.clearText()
  • ViewActions.replaceText()

perform() 方法还会再次返回一个 ViewInteraction 的对象, 也就是说你可以执行更多的操作或者验证结果. 而且你也可以通过 perform() 方法的可变参数来指定多个操作.

验证测试结果

调用 ViewInteraction.check() 方法可以断言一个 View 的状态. 这个方法需要一个 ViewAssertion 类型的对象作为参数. ViewAssertion 类提供了用于创建这些对象的辅助方法.

  • maches() - Hamcrest 匹配器
  • doesNotExist() - 断言选中的 View 不存在

你也可以使用强大的 Hamcrest 匹配器. 下面给出了部分示例:

onView(withText(startsWith("ABC"))).perform(click());// 1.onView(withText(endsWith("YYZZ"))).perform(click()); // 2.onView(withId(R.id.viewId)).check(matches(withContentDescription(containsString("YYZZ")))); // 3.onView(withText(equalToIgnoringCase("xxYY"))).perform(click()); // 4.onView(withText(equalToIgnoringWhiteSpace("XX YY ZZ"))).perform(click()); // 5.onView(withId(R.id.viewId)).check(matches(withText(not(containsString("YYZZ"))))); // 6.

① 匹配以文本 “ABC” 开头的 View

② 匹配以文本 “YYZZ” 结尾的 View

③ 匹配指定 id View 的且检查文本内容包含 “YYZZ”

④ 匹配一个含有指定字符串的 View, 并且该字符串忽略大小写

⑤ 匹配一个含有指定字符串的 View, 并且该字符串忽略空白字符

⑥ 匹配指定 id View 的且检查文本内容不包含 “YYZZ”

访问 instrumentation API

通过 InstrumentationRegistry.getTargetContext() 可以访问到测试应用的上下文, 例如你想使用字符串 id 而不是 R.id, 下面的方法可以帮助你实现:

/*** Created by zhanglulu on 2018/3/6.*/
@RunWith(AndroidJUnit4.class)
public class EspressoTest2ActivityTest {@Rulepublic ActivityTestRule<EspressoTest2Activity> mRule =new ActivityTestRule<EspressoTest2Activity>(EspressoTest2Activity.class);@Testpublic void buttonShouldUpdateText(){onView(withId(R.id.resultView)).perform(click());onView(withId(getResourceId("Click"))).check(matches(withText("Done")));}/*** 根据 id 字符串获取真实 id* @param idStr* @return*/private static int getResourceId(String idStr) {Context targetContext = InstrumentationRegistry.getTargetContext();String packageName = targetContext.getPackageName();return targetContext.getResources().getIdentifier(idStr, "id", packageName);}
}

配置Activity的启动 Intent

如果你给 ActivityTestRule 构造方法的第三个参数指定为 false, 则可以配置启动 Intent, 并手动启动测试 Activity.

/*** Created by zhanglulu on 2018/3/6.*/
@RunWith(AndroidJUnit4.class)
public class EspressoTest2ActivityTest {@Rulepublic ActivityTestRule<EspressoTest2Activity> mRule =new ActivityTestRule<EspressoTest2Activity>(EspressoTest2Activity.class, true, false);@Testpublic void demonstrateIntentPrep() {Intent intent = new Intent();intent.putExtra("input", "Test");mRule.launchActivity(intent);onView(withId(R.id.resultView)).check(matches(withText("Test")));}
}

Adapter Views

AdapterView 是一种特殊的组件, 它可以动态的从 Adapter 中加载数据. 只有一部分数据在 View 层次结构中有真实的 View. onView() 不会为这些数据找到相应的 View. 而 onData() 可以与 Adapter 进行交互, 找到对应的 View, 例如 ListView. 下面给出部分示例:

@Test
public void testList() {// 点击 ListView 中文本为 "测试 15" 的 itemonData(allOf(is(instanceOf(String.class)), is("测试 30"))).perform(click());onData(allOf(is(instanceOf(String.class)), is("测试 1"))).perform(click());onData(allOf(is(instanceOf(String.class)), is("测试 49"))).perform(click());
}

Espresso 测试添加权限

可以通过 instrumentation API 给你的测试执行授予权限的操作.如下面示例:

@Before
public void grantPermission() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {getInstrumentation().getUiAutomation().executeShellCommand("pm grant " + getInstrumentation().getTargetContext().getPackageName()+ " android.permission.CALL_PHONE");}
}

Espresso UI Recorder

Android Studio 在测试菜单栏上提供了一个 Run ▸ Record Espresso Test 的功能, 它可以记录下你与应用程序的交互并从中创建 Espresso 测试.

点击运行,之后 Android Studio 将记录下你与应用的交互行为,并生成测试代码.

访问当前的 Activity

你还可以访问正在进行测试的 Activity 对象,并调用它的方法. 例如,你有下面的 TestConfigureActivity, 并存在一个方法 configureActivity().

public class TestConfigureActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test_configure);}// 外部调用public void configureActivity(String Uri) {// do something with this}public void onClick(View view) {startActivity(new Intent(this, SecondActivity.class));}
}

如果你想在测试方法中得到这个 Activity 并且执行里面的方法, 你可以通过 ActivityTestRule 来获取, 示例如下:

@Test
public void useAppContext() throws Exception{TestConfigureActivity activity = mRule.getActivity();activity.configureActivity("https://testurl");//do more
}

并且你也可以重写 ActivityTestRule 类来配置你的测试 Activity.例如:

@Rulepublic ActivityTestRule<TestConfigureActivity> mRule =new ActivityTestRule<TestConfigureActivity>(TestConfigureActivity.class){@Overrideprotected void beforeActivityLaunched() {super.beforeActivityLaunched();//Activity 启动前做些事情}@Overrideprotected void afterActivityLaunched() {super.afterActivityLaunched();//Activity 启动后做些事情}};

你甚至可以拿到前台的 Activity 的实例.这里着重说明一下, 你所测试的 Activity 不一定都在前台显示, 例如,你从当前测试的 Activity (也就是你在 ActivityTestRule 传入的 Activity) 跳转到另外的一个 Activity, 此时在前台的 Activity 就是另外的一个 Activity. 这个时候就可以通过 ActivityLifecycleMonitorRegistry 来获取前台的 Activity, 示例如下:

@Test
public void navigate() {onView(withText("Next")).perform(click());Activity activity = getActivityInstance();boolean b = (activity instanceof SecondActivity);assertTrue(b);// do more
}public Activity getActivityInstance() {final Activity[] activity = new Activity[1];InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {Activity currentActivity = null;Collection resumedActivities =ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(RESUMED);if (resumedActivities.iterator().hasNext()){currentActivity = (Activity) resumedActivities.iterator ().next();activity[0] = currentActivity;}});return activity[0];
}

需要注意的是 ActivityLifecycleMonitorRegistry 并不是标准的 API, 所以可能在后期名称会发生变化.

运行 Espresso 测试输出测试报告

  1. 使用 Android Studio

右击你的测试类, 并点击运行就 OK 了.

  1. 使用 Gradle

通过 Gradle 执行 connectedCheck Task 可以执行测试目录下所有的测试用例.

执行结束后将会在 app/build/reports 目录下生成测试报告, 点击打开 index.html 即可查看.

检查 Taost

下面是一个点击 Item ,并检查 Toast 是否弹出的测试.

@Test
public void testToast() {onData(allOf(instanceOf(String.class), is("测试 20"))).perform(click());onView(withText(startsWith("点击"))).inRoot(withDecorView(not(is(mRule.getActivity().getWindow().getDecorView())))).check(matches(isDisplayed()));
}

通过Espresso Intents模拟Intent

Espresso 也提供了模拟 Intent 的功能. 它可以检查一个 Activity 是否正常发出一个正确的 Intent.如果它接收了正确 Intent 则测试通过.

Espresso Intents 通过 com.android.support.test.espresso:espresso-intents 依赖提供.

使用 Espresso Intents 必须使用 IntentTestRule 而不是 ActivityTestRule.下面是一个简单的示例:

/*** Created by zhanglulu on 2018/3/7.*/
@RunWith(AndroidJUnit4.class)
public class TestIntent {@Rulepublic IntentsTestRule<EspressoTest1Activity> mIntentTestRule =new IntentsTestRule<EspressoTest1Activity>(EspressoTest1Activity.class);@Testpublic void triggerIntentTest() {onView(withId(R.id.switchActivity)).perform(click());intended(allOf(hasAction(Intent.ACTION_CALL),hasData("123456789"),toPackage(InstrumentationRegistry.getTargetContext().getPackageName()),hasExtra("input", "Test")));}
}

更多详细内容请移步: https://developer.android.com/training/testing/espresso/intents.html#matching

Espresso的详细使用相关推荐

  1. Espresso环境搭建及其基本使用

    大家开发Java程序的时候可以使用JUnit进行程序的测试,现在有一款可以测试Android UI的框架,叫Espresso,在这,简单记录下环境搭建及其基本使用. 官方的介绍:Espresso 学习 ...

  2. android espresso web,Espresso Web

    Espresso-Web 是一个与 Android WebView 界面组件一起使用的入口点.Espresso-Web 重复使用常用 WebDriver API 中的 Atom 来检查和控制 WebV ...

  3. java espresso车架_Espresso 学习

    Espresso 学习 针对源码测试 针对源码的测试,其实在google 的官方网站 Espresso 介绍就有,此外,还可以在Espresso guide上看到更详细的介绍和 demo.这里就简单提 ...

  4. android espresso 教程,Android Espresso入门到自动搞定

    没有捕抓不到的猎物,就看你有没有野心去捕抓:没有完成不了的事情,就看你有没有野心去做. ----<狼道> 目录 一.前言 二.简介 (1)是什么 (2)有什么用 (3)怎么用 1.添加依赖 ...

  5. java espresso车架_Espresso UI自动化测试框架

    前言 Espresso是谷歌大力推荐的一套测试框架,从Android studio2.2版本开始,google就开始支持在as上espresso自动生成单元测试代码. Espresso测试运行速度很快 ...

  6. Espresso Test 3: Fragment Test

    Espresso Fragment Test 这是 Espresso 的第二篇,Fragment 的 UI 测试. 它包括两部分内容, 一是测试 fragment 的 UI 测试,另外一部分是 fra ...

  7. java espresso_java – 带有片段的Android Espresso功能测试

    我的应用程序中有三个活动 >登录活动 >一项主要活动 >详细活动 我想使用espresso来测试一系列事件:单击登录活动上的登录按钮,打开主活动,然后单击主活动中的列表项,打开详细活 ...

  8. java espresso车架,只爱钢架公路:Casati Espresso

    本帖最后由 spinosae 于 2017-1-2 18:49 编辑 DSCF1176_s.JPEG (231.79 KB, 下载次数: 27) 2017-1-2 16:08 上传 #品牌 Casat ...

  9. Android UI 测试框架Espresso详解

    Android UI 测试框架Espresso详解 1. Espresso测试框架 2.提供Intents Espresso 2.1.安装 2.2.为Espresso配置Gradle构建文件 2.3. ...

最新文章

  1. python unsupported operand type(s) for /: 'str' and 'str' can only concatenate str (not int) to s
  2. 用python计算贷款_Python基于Logistic回归建模计算某银行在降低贷款拖欠率的数据示例...
  3. 理解Event的冒泡模型
  4. ABAP很厉害是怎么一种体验?
  5. BZOJ 2460: [BeiJing2011]元素 线性基
  6. 求树的直径+并查集(bfs,dfs都可以)hdu4514
  7. python 贝塞尔曲线 反算控制点_根据贝塞尔曲线上的点反算t值
  8. 储存管理系统c语言,C语言-图书管理系统-未做文件储存系统.docx
  9. session简单学习2
  10. 【Scratch编程案例教学】scratch消灭砖块 scratch编程案例教学 少儿编程教案
  11. jeesite应用实战(数据增删改查),认真读完后10分钟就能开发一个模块
  12. 摄像机标定原理与操作
  13. 碧桂园+电子签章系统,打造印控中台,实现集团印章管控一体化
  14. 在react中使用codemirror
  15. 王垠:如何掌握程序语言
  16. 从互联网大厂跳槽到国企后,我发现没有一劳永逸的工作。。。
  17. from scipy.misc import comb ImportError: cannot import name comb
  18. 混合开发模式下主流移动开发平台分析
  19. 最新版学习笔记---Python机器学习基础教程(1)Irises(鸢尾花)分类---附完整代码
  20. 懒癌必备-dplyr和data.table让你的数据分析事半功倍

热门文章

  1. C语言32位系统下基本类型数据所占字节数
  2. spring-cloud-context源码解读
  3. 白嫖阿里-----搭建个人服务
  4. python keyboard hook_[python] PyMouse、PyKeyboard用python操作鼠标和键盘
  5. 解决vmbox虚拟机 能上网,能ping通宿机,但是宿机 ping 不通 虚拟机
  6. Java 春招、秋招面试总结
  7. 客户端和服务器的通信协议,客户端和服务器的通信协议
  8. 分享几个实用的神器APP系列(三)
  9. 【linux3.10】内存反向映射中的anon_vma是per process的吗?
  10. Java各个版本区别