没有捕抓不到的猎物,就看你有没有野心去捕抓;没有完成不了的事情,就看你有没有野心去做。 ————《狼道》

目录

一、前言

二、简介

(1)是什么

(2)有什么用

(3)怎么用

1.添加依赖

2.基本使用

3.基础知识

4.方法介绍

5.错误处理

6.自动生成测试用例

三、原理

(4)原理是什么

四、总结

(5)优点与缺点

五、内容推荐

六、项目参考

一、前言

很早之前写过一篇《JUnit单元测试》,比较简单常用的测试方法。写的只能算是入门知识也不算很细。后面又用过UI Automator与Espresso,不过都没好好总结。最近刚好需要重新回顾了一下,顺便也做下记录。UI Automator与Espresso都是Android自动化测试框架,各有优缺点,不过个人相比起来更喜欢后者。这里就给大家简单介绍下Espresso,整体大纲如下

二、简介

(1)是什么

Espresso是一个非常强大的Android UI测试框架。功能类似于ui Automator,但测试由熟悉被测代码库的人来编写最好。

(2)有什么用

使用Espresso可模拟用户操作、检测数据编写简洁、漂亮、可靠的Android UI测试。

(3)怎么用

1.添加依赖

androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'

androidTestImplementation 'androidx.test:runner:1.1.0'

androidTestImplementation 'androidx.test:rules:1.1.0'

//可选 提供ApplicationProvider.getApplicationContext()

androidTestImplementation 'androidx.test:core:1.2.0'

2.基本使用

//公式:

onView(withId(R.id.greet_button)).perform(ViewAction).check(ViewAssertion);

onData(ObjectMatcher).DataOptions.perform(ViewAction).check(ViewAssertion);

根据下面例子,给大家简单解释下这些方法的作用

@RunWith(AndroidJUnit4.class)

@LargeTest

public class MainActivityTest {

//启动Activity 不懂Rule可查阅junit.@Rule类似于@Before

@Rule

public ActivityTestRule mActivityTestRule = new ActivityTestRule<>(MainActivity.class);

@Test

public void mainActivityTest() {

//2.withId()匹配控件(View)id,其它匹配方法可在ViewMatchers类中获得,如:withText()

Matcher viewMatcher = withId(R.id.xxx);

//1.onView()、onData()是启动测试的入口 ,通过传入匹配器(Matcher)获取ViewInteraction实例来执行一些测试操作

ViewInteraction viewInteraction = onView(viewMatcher);

//3.通过ViewInteraction.perform() 执行操作。操作的方法在 ViewActions中,如:click()点击

viewInteraction.perform(click());

//5.通过通过ViewInteractions类获取到viewInteraction对象

ViewAssertion viewAssertion = doesNotExist();//表示不存

ViewAssertions.matches(withText("xxx"));//表示匹配"xxx"等文字内容

//4.通过ViewInteraction.check()执行检测ViewAssertion对象

viewInteraction.check(viewAssertion);

//简单写法: 表示根据ID找到指定控件后执行点击操作并匹配文本是不是“关闭”内容

onView(withId(R.id.btn_close)).perform(click()).check(matches(withText("关闭")));

//表示根据文本找到指定控件后执行点击操作并匹配是否可点击

onView(withText("关闭")).perform(click()).check(matches(isClickable()));

}

}

看了上面例子基本可以操作大部分的控件了,但是仍有个别的控件得需要特殊对待。如ListView

@Test

public void mainActivityTest() {

// ListView 来自https://academy.realm.io/posts/chiu-ki-chan-advanced-android-espresso-testing/

onData(withValue(27)).inAdapterView(withId(R.id.list)).perform(click());

}

//定义匹配器 不了解的可以看看这篇https://www.jianshu.com/p/662a07e5e828

public static Matcher withValue(final int value) {

return new BoundedMatcher(MainActivity.Item.class) {

@Override public void describeTo(Description description) {

description.appendText("has value" + value);

}

@Override public boolean matchesSafely(MainActivity.Item item) {

return item.toString().equals(String.valueOf(value));

}

};

}

更多特别的使用这里就不举例了。写起来可能有点多

3.基础知识

①基本组成部分

Espresso:与视图交互的入口点(通过onView()和onData())

ViewMatchers:在当前View层级去匹配指定的View。您可以将其中一个或多个传递给onView()方法

ViewActions:执行Views的某些行为,如点击事件

ViewAssertions:检查Views的某些状态,如是否显示

②执行操作

点击事件:onView(...).perform(click());

执行多个操作:onView(...).perform(typeText("Hello"), click());

检查是否匹配文本:onView(...).check(matches(withText("Hello!")));

适配器相关操作:onData(allOf(is(instanceOf(String.class)), is("Americano"))).perform(click());

onView(withId(R.id.spinnertext_simple)).check(matches(withText(containsString("Americano"))));

③获取控件

具有唯一ID:onView(withId(R.id.my_view));

具有多个相同ID根据属性:onView(allOf(withId(R.id.my_view), withText("Hello!")));

无法具体匹配情况下:onView(allOf(withId(R.id.my_view), not(withText("Unwanted"))));

注意事项:

如果无法使用withText()或withContentDescription()缩小搜索范围,可以考虑将其视为可访问性错误

使用最不具描述性的匹配器来查找要查找的视图。不要过度指定,因为这将迫使框架做更多不必要的工作

如果目标视图位于adapterview(如ListView、GridView或spinner)中,则onView()方法可能无法工作。在这些情况下,应该使用onData()

4.方法介绍

①常用方法:

public void fun(){

1.Espresso类

//测试入口

onData(Matcher extends Object> dataMatcher)、onView(Matcher viewMatcher)

//关闭软键盘

closeSoftKeyboard();

//循环主线程,直到应用程序空闲 onIdle();

onIdle(Callable action)

//打开在ActionBar中显示的溢出菜单

openActionBarOverflowOrOptionsMenu(this);

openContextualActionModeOverflowMenu();

//按下后退按钮。

pressBack();

//与pressBack()类似,但当Espresso导航到应用程序或测试中的进程之外时,不会抛出异常

pressBackUnconditionally();

//将默认的FailureHandler更改为给定的

setFailureHandler();

2.ViewMatchers类 与onData、onView配合定位view

//匹配文本

withText(Matcher stringMatcher)

withText(String text)

withText(int resourceId)

//匹配背景

hasBackground(int drawableId)

//匹配子元素数目

hasChildCount(int childCount)

//匹配id

withId(Matcher integerMatcher)

withId(int id)

//匹配类名字

withClassName(Matcher classNameMatcher)

//匹配资源名

withResourceName(String name)

//匹配具有焦点、选中状态、可单击、显示状态

hasFocus()/isChecked()/isClickable()/isDisplayed()

3.ViewActions类 模拟用户操作 与Espresso.perform(ViewAction... viewActions)

//点击、双击、点击长按

click()、 doubleClick()、longClick()

//关闭软键盘、滚动视图

closeSoftKeyboard()、scrollTo()

//向下滑动、向左滑动、向右滑动、向上滑动

swipeDown()、swipeLeft()、swipeRight()、 swipeUp()

//输入文本

typeText(String stringToBeTyped)

4.ViewAssertions类 断言

//返回一个断言,该断言确保视图匹配器在层次结构中没有找到任何匹配的视图

doesNotExist()

//断言视图存在于视图层次结构中,并由给定的视图匹配器匹配

matches(Matcher super View> viewMatcher)

}

5.错误处理

@Before

public void setUp() throws Exception {

//ApplicationProvider需要androidTestImplementation 'androidx.test:core:1.2.0'

setFailureHandler(new

CustomFailureHandler(ApplicationProvider.getApplicationContext()));

}

private static class CustomFailureHandler implements FailureHandler {

private final FailureHandler delegate;

public CustomFailureHandler(Context targetContext) {

delegate = new DefaultFailureHandler(targetContext);

}

@Override

public void handle(Throwable error, Matcher viewMatcher) {

try {

delegate.handle(error, viewMatcher);

} catch (NoMatchingViewException e) {

// throw new MySpecialException(e);

System.out.println("打印异常:"+e.getMessage());

}

}

}

注意:在您的测试设备上关闭动画

①组成部分 1.界面交互 2.View 元素断言

②生成步骤

1.记录界面交互

依次点击 Run > Record Espresso Test。

在 Run > Select Deployment Target 窗口中,选择要在哪个设备上记录测试。

Record Your Test 窗口将在应用启动后显示

2.添加断言以验证界面元素

text is:检查选定 View 元素的文本内容

exists:检查 View 元素是否存在于屏幕上可见的当前 View 层次结构中

does not exist:检查 View 元素是否不存在于当前 View 层次结构中

操作步骤:

点击 Add Assertion

当前屏幕的布局将显示在 Record Your Test 窗口右侧的面板中

从 Edit assertion 框的第二个下拉菜单中选择要使用的断言

点击 Save and Add Another 以再创建一个断言,或点击 Save Assertion 以关闭断言面板

3.保存记录

点击 Complete Recording。此时将显示 Pick a test class name for your test 窗口

Espresso 测试记录器会根据已启动 Activity 的名称在软件包内为您的测试提供一个唯一的名称

文件将在 Espresso 测试记录器生成它后自动打开,Android Studio 将显示在 IDE 的 Project 窗口中选择的测试类

最后一点很好用,不想写代码的可以好好利用。但是不一定比自己写的快,只要把基础代码封装好。编写起来也很快。

三、原理

(4)原理是什么

因为是测试方面的框架,所以分析起来对我来说还是有点难度。所以这里就不献丑了,网上看到过一篇就推荐给大家,想更详细了解的可以看看https://www.jianshu.com/p/1fb248b77b36

四、总结

(5)优缺点

个人使用过程中与UI Automator做了些对比。

API接口比较少,代码简洁,使用方便,运行速度快

AS提供可自动生成编码测试的工具

适合由熟悉项目人来编写,自动生成除外

无需主动写Sleep等待UI事件的执行和UI的绘制

运行测试前需关闭动画

五、内容推荐

六、项目参考

单元测试、UI Automator与Espresso基础代码都放在下面的项目中,有兴趣的可以看下。

Github:BLCS —— apk下载体验地址

若您发现文章中存在错误或不足的地方,希望您能指出!

android espresso 教程,Android Espresso入门到自动搞定相关推荐

  1. Android精通教程-Android入门简介

    前言 大家好,我是 Vic,今天给大家带来Android精通教程-Android入门简介的概述,希望你们喜欢 每日一句 If life were predictable it would cease ...

  2. Android 相机教程,Android 相机教程

    Android相机教程 相机主要用于捕获图片和视频.我们可以通过使用相机API的方法来控制相机. Android通过以下两种方式提供了在相机上工作的功能: 通过相机意图 通过相机API 了解相机意图和 ...

  3. Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅

    原文:Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅 在前几期中总结分享了Android的前世今生.Android 系统架构和应用组件那些事.带你一起来聊一聊Android开发 ...

  4. android开发教程,android开发入门教程

    所谓知己知彼才能百战百胜,想学好android就必须先了解 android是什么意思 android环境搭建 Android一词的本义指"机器人",同时也是Google于2007年 ...

  5. android fragment 教程,Android app开发中的Fragment入门学习教程

    在Android3.0上开始引入了一个新概念叫Fragment.它有自己的布局文件,可以作为组件排布,也可以相互组合去实现不同的布局显示.使用Fragment可以重复利用代码,并且可以满足不同设备尺寸 ...

  6. android+notepad教程,Android平台应用开发实例:Notepad

    在这个教程中将会建立一个简单列表界面,允许用户添加删除,但是不能编辑.包括如下的内容: ◆ListActivities的基础知识和如何建立菜单项. ◆如何使用SQLite 数据库访问数据. ◆如何使用 ...

  7. android打开教程,Android 打开网络上pdf文件

    1.基本思路: 打开网络pdf 思路整体还是来源与图片的加载. android中加载网络图片的框架有很多个.如image-laoder, fresco.glide等,首先都是从内存中找图片,如果内存中 ...

  8. android gridview教程,Android系列教程之GridView组件的使用

    GridView是一个网络布局的视图,他能让你的元素显示在一个个的格子里.我们的桌面就是一个GridView.. 1.新建一个gridview工程,activity_main.xml的代码如下:< ...

  9. sqlite数据库android使用教程,Android开发教程之 SQLite数据库的使用

    在开发Android应用程序时经常需要存储数据,Android系统提供了SQLite数据库,还提供了SQLiteOpenHelper类,使我们可以很方便的操作数据库.通过一个例子来说明在Android ...

最新文章

  1. Graph + AI 2021中国峰会:TigerGraph与行业共探图与AI应用前景
  2. HDU5726 GCD(rmq+二分)
  3. JSP学习笔记(一):JSP语法和指令
  4. java中JList的setSelectionMode()详解
  5. mvc html.displayfor,我想了解@ Html.DisplayFor(modelItem = item.FirstName)中的lambda表达式...
  6. gcc,cc,g++,CC的区别
  7. 深度强化学习-DDPG算法原理和实现
  8. overleaf入门
  9. Python计算前n个自然数的阶乘和
  10. 我对软件发展的思考,一个不变却一直在变的话题
  11. magento url rewrite规则
  12. 每天10个Linux命令四
  13. PassFab iPhone Unlocker安装方法
  14. R 学习 - 火山图
  15. 怎么把ide改成ahci_Win10系统无需重装,硬盘IDE改为AHCI模式的方法
  16. PART 3.3 风控建模卡方分箱计算篇
  17. 智课雅思短语---三、unshakable duty
  18. 师父韩晋文先生传授的八卦掌套路
  19. Android 知识点 108 —— PowerManagerService
  20. html怎样制作纵向表格,html制作细线表格的简单实例

热门文章

  1. 找到数组里面缺失的数(C++(绝妙方法))
  2. 计算机系统与配置要求,电脑系统以及Adobe Audition的版本配置要求-喜马拉雅
  3. div做表格 html5,div+css制作表格
  4. MySQL复制 slave_exec_mode 参数IDEMPOTENT 说明
  5. Java - Eclipse: Error notifying a preference change listener
  6. 如何旋转PDF的页面方向?教你2种方法
  7. 三菱FX5U控制10轴伺服的设备成套电气图纸
  8. 遥感原始图像计算机格式,卫星遥感影像数据是什么样格式的?
  9. Thingworx配置mysql的jdbc
  10. JAVA 数组降序排列思路