到目前为止,我们已经完成了对Espresso
的介绍。从之前的文章我们可以看到,Espresso
对Android APP的自动化测试提供了一系列非常强大的工具和方法。
现在试想这样一个场景:我们在APP中有一个更改头像的功能,此时我们需要调用系统相机进行拍照,然后再回到APP提交拍好的照片。在这种场景下,我们需要从自己的APP跳转到其他的APP,而这种跳转的交互在产品中是经常会发生的。
Espresso
并没有对这种跨APP的交互测试提供支持。我们无法在脚本中通过Espresso
获取到非自己APP之外其他APP(或者系统界面)的UI组件。这时,我们就需要用到Android提供的UI Automator
来进行自动化测试。
配置
想要使用UI Automator
,只需要添加如下依赖:
dependencies {
...
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1'
}
UI Automator
仅支持Android 4.3(API Level 18)及以上版本。
可行性探索
在使用UI Automator
编写测试脚本之前,我们需要对当前测试用例是否可以用UI Automator
进行测试做一些探索。简单来说,就是要确保我们需要的界面元素是否都能找到、希望出发的操作是否都支持。
确定可行性的方法也很简单,只要确保我们需要操作的UI元素有可以进行匹配的属性(这一点类似于Espresso
),比如唯一的ID,text等等。我们可以按照该系列第四篇对uiautomatorviewer的介绍来使用Android提供的uiautomatorviewer
工具,对测试用例中的各个页面,尤其是跨APP交互的页面中的各个UI元素进行分析,确保每个我们需要操作的元素都有相应可以匹配的属性值,以便于我们可以通过脚本找到相应的元素。
对此,Android官方对我们开发者也提出了一些针对自动化测试的建议,便于我们在开发时采用:
对于
ImageView
,ImageButton
,CheckBox
这些控件,对其设置android:contentDescription
属性。对于
EditText
,设置其android:hint
属性。对于其他有交互作用但没有显式文本的控件(比方说可以点击的icon之类),设置其
android:hint
属性。
以上这些建议的目的,无非就是可以让我们通过自动化测试API去找到页面上的控件。
UI Automator测试流程
使用UI Automator
进行脚本编写的一些前置条件和Espresso
基本类似,实际上,我们基于之前几篇文章的配置就可以直接进行UI Automator
的编写。
采用UI Automator
的过程如下:
获得一个
UiDevice
对象,代表我们正在执行测试的设备。该对象可以通过一个getInstance()
方法获取,入参为一个Instrumentation
对象:
UiDevice mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
通过
findObject()
方法获取到一个UiObject
对象,代表我们需要执行测试的UI组件。对该UI组件执行一系列操作。
检查操作的结果是否符合预期。
整个流程和Espresso
基本类似,除了增加了第一项:首先获得一个UiDevice
对象。这一点也容易理解,为了要支持跨APP的测试,我们就不能只从APP层面而是需要从整个设备层面来进行测试了,因此也是首先需要获取设备对象,再执行相关的操作。
获取UI组件
根据如上所说,我们是通过UiDevice
来调用findObject()
方法来获取到我们想要执行操作的UI组件。我们来看一下这个方法的声明:
/**
* Returns a UiObject which represents a view that matches the specified selector criteria.
*
* @param selector
* @return UiObject object
*/
public UiObject findObject(UiSelector selector) {
return new UiObject(this, selector);
}
从如上声明可以看出,findObject()
方法接受了一个UiSelector
对象,返回了我们需要的UiObject
对象。在这里,UiSelector
类似于Espresso
中的Matcher
,也是指定了某种匹配规则,UI Automator
会按照UiSelector
指定的规则从当前UI上进行控件的查找。不同于Espresso
的是,如果找到多个满足规则的控件,则会返回第一个控件。如果没有控件满足当前指定的规则,则会抛出一个UiAutomatorObjectNotFoundException
异常。
和Espresso
类似,我们可以通过ID
、text
等属性来进行控件的查找,同时也可以指定目标控件的类型。可以指定一个规则,也可以通过链式调用指定多个规则。比如:
UiObject mCameraSureBtn = mDevice.findObject(new UiSelector().resourceId("com.android.camera:id/v6_btn_done")
.className("android.widget.ImageView"));
这行代码的UiSelector
构建就是采用了如下两个组合规则:
控件
ID
为"com.android.camera:id/v6_btn_done"
,这个ID
是从某个MIUI版本系统的系统相机获取的,对应于拍照按钮;控件类型为
ImageView
。
除了UiObject
之外,UI Automator
还提供了其他的UI对象,比如UiCollection
对象可以对一组控件之间进行操作,对布局之间的包含关系做了支持;比如UiScrollable
对象支持了对可滑动组件的支持。这些组件的用法大同小异,可以自行参考API接口。
执行操作
找到了我们需要的控件,接下来该对控件进行操作了!
UiObject
提供了一系列方法用来执行各种各样的操作。比如:
click()
:点击控件中心;dragTo()
:拖动控件到指定位置;setText()
:对可输入控件设置文本;swipeUp()
:对控件执行上滑操作。类似地,swipeDown()
,swipeLeft()
和swipeRight()
可以执行相应的操作
这一部分也是比较简单,和Espresso
的用法大体类似,只是API层面的区别。具体的可以在使用的时候查看API文档。
检查结果
执行一系列操作之后,我们需要对操作的结果进行验证了!
对于结果的验证,我们可以使用之前说到的一系列Assert
方法了。比如说,我们需要检测某个控件的文字:
assertEquals(TargetText, mUiObject.getText())
便可以这样进行执行。
总结
从该篇文章来看,UI Automator
的使用方法和Espresso
基本相同,整体的思路也是完全一致,只是一个对APP内部提供了很好的支持,另一个对跨APP提供了支持。大家在实际编写自动化测试脚本时可以灵活选用。
附录
Android自动化测试-从入门到入门(1) Hello Testing!
Android自动化测试-从入门到入门(2) Testing APIs
Android自动化测试-从入门到入门(3) Espresso入门
Android自动化测试-从入门到入门(4) uiautomatorviewer
Android自动化测试-从入门到入门(5) AdapterView的测试
Android自动化测试-从入门到入门(6) 会玩的Espresso
Android自动化测试-从入门到入门(7) UI Automator
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。