新手区 Android uiautomator 使用入门官方教程

Tcat · 2015年06月24日 · 最后由 Monkey 回复于 2015年06月25日 · 810 次阅读

这是自己笔记记录的,具体来源忘记了

Android SDK 提供下述工具;来支持自动化的功能界面测试:
uiautomatorviewer – A GUI tool to scan and analyze the UI components of an Android application. 扫描、分析待测应用的 UI 组件的图像工具
uiautomator – A Java library containing APIs to create customized functional UI tests, and an execution engine to automate and run the tests. 包含创建定制功能界面测试 API 和自动化运行测试用例的引擎的 JAVA 类库。

使用 uiautomator 测试框架的工作流程

简单介绍下 UI 自动化测试的主要步骤:
Prepare to test by installing the app on a test device, analyzing the app’s UI components, and ensuring that your application is accessible by the test automation framework. 安装待测应用到待测设备,准备测试,分享待测应用的 UI 组件,区别待测应用可以被 uiautomator 测试框架访问。

Create automated tests to simulate specific user interactions on your application. 创建自动化测试来模拟指定的用户和待测应用的交互

Compile your test cases into a JAR file and install it on your test device along with your app. 编译测试用例成 jar 文件,安装到装有待测应用的待测设备上

Run the tests and view the test results. 执行测试、检查测试结果

Correct any bugs or defects discovered in testing .修正测试时发现的缺陷

在写测试用例之前,你最好熟悉待测应用的 UI 组件(包括视图 views 和控件 controls)。 uiautomatorviewer 可以帮助你实现这一点,uiautomatorviewer 获取当前 UI 界面的快照,提供一个可视化的界面,来检查布 局层次、查看每一个显示在设备上的 UI 组件的属性。在以后的 uiautomator 测试中,你可以利用 uiautomator 提供的信息来选择特定的 UI 组件。
分析待测程序的 UI 组件的步骤:

  • 1. 将 android 设备连接到有开发环境机器上
  • 2. 打开命令行终端窗口,进入 android sdk tool 所在目录
  • 3. 运行以下命令: shell $ uiautomatorviewer
    1. 捕获到待分析的界面后,点击设备快照 “Device Screenshot” 按钮 注意:如果你连接了多个设备,需要指定 ANDROID_SERIAL 环境变量,来说明对哪个设备进行截屏:
    • 1. 运行以下命令,找到你的设备序列号 shell $ adb devices
    • 2. 设置环境变量 ANDROID_SERIAL
    • 在 windows 上: shell set ANDROID_SERIAL=<device serial number>
    • 在 linuix 上: shell export ANDROID_SERIAL=<device serial number> 如果你只连接一个设备,则不需要设置
    1. 查看应用的 UI 属性
    • 1. 在快照的左侧面板上,可以看到 uiautomatorviewer 显示的 UI 组件;在右侧,下边是组件的属性,上边是布局的层次
    • 2. 你也可以点击” Toggle NAF Nodes“按钮,来显示 uiautomator 框架无法访问的 UI 组件。对于那些组件,只有有限的属性信息可以供 uiautomator 使用。

在编写 uiautomator 测试前,首先识别待测应用的 UI 组件。一般来说,适合测试的是可以访问的,用户可以交互的 UI 组件。UI 组件还应该包含可见的文本标签, android:contentDescription 值,或全部。可以使用 uiautomatorviewer 工具来方便地查看待测应用在屏幕上的可见 对象。关于如何使用该工具分析应用屏幕的更多信息,可以参考本文档的相应部分。关于安卓提供的通用类型的 UI 组件,可以参考安卓官方文档。
确保待测应用可访问
本步骤非常必要,因为 uiautomator 工具依赖安卓的可访问特性来执行功能界面测试。你应该在你的程序中加入下述简单的优化来支持 uiautomator 测试框架:
使用 android:contentDescription 属性作为 ImageButton , ImageView , CheckBox 和其他界面控件的标签

为 EditText 输入框提供 android:hint 属性,而不是 android:contentDescription
用于反馈给用户信息(如状态、声明信息)的控件的图标应该包含 android:hint 属性

确保在使用方向控制键(如 trackball 或 D-pad)时所有的 UI 元素也是可访问的
使用 uiautomatorviewer 工具确保 UI 组件可以被 uiautomator 工具访问。你还能通过打开如 TalkBack 或 Explore by Touch 的可访问服务,使用方向控制键盘来测试应用的可访问性。

备注:为识别不可访问的 UI 组件,使用 uiautomatorviewer 工具的的 Toggle NAF Nodes 选项。通常,android 应用开发者不需要考虑是否支持可访问性,既然 UI 组件继承 View 和 ViewGroup 类。然而,对于使用定制试图 组件提供用户体验的应用,无法获得自由标准 androidUI 组件才有的可访问性支持。如果你的测试项目有类似情况,确保应用开发者通过实现 AccessibilityNodeProvider 接口类来 暴露定制组件给 android 可访问性服务。关于更多信息,可以参考 android 官方站点。

配置测试开发环境

右击新建的项目,选择属性-java 构建路径,完成下述设置:
Click Add Library > JUnit then select JUnit3 to add JUnit support. 添加 junit3 类库,支持 junit。
Click Add External JARs… and navigate to the SDK directory. Under the platforms directory, select the latest SDK version and add both the uiautomator.jar and android.jar files. 添加类库 uiautomator.jar 和 android.jar。
若测试环境开发环境部署 eclipse,确保 /platforms/目录下的 uiautomator.jar 和 android.jar 在类路径中。一旦完成上述配置,就可以开始编写 uiautomator 测试用例了
创建 uiautomator 测试用例
为创建使用 uiautomator 测试框架的测试,创建继承 UiAutomatorTestCase 类的测试用例即可。在 eclipse 中, 测试用例文件维护在项目的 src 文件中。稍后,会被测试用例构建为 jar 文件,然后复制 jar 文件到待测设备。jar 文件不是 APK 文件,独立存在于待测 设备上的待测应用。因为 the UiAutomatorTestCase 继承 junit.framework.TestCase,可以使用 junit 断言类 Assert 来验证 UI 元素放火期望的结 果。为了解更多关于 JUnit 的姿势,可以访问 junit.org 站点。创建测试用例时,首先应该访问包含待测应用的待测设备。最佳实践是,从设备的主屏 幕开始运行测试。从主屏幕开始,你能使用 uiautomator 提供的 API 类来模拟用户动作、检测 UI 组件。本文提供一个例子来演示如何使用 uiautomator 执行测试。

编程接口 API

包含 uiautomator API 的 uiautomator.jar 位于 /platforms/ 目录下,uiautomator API 包含关键的类,可以用来捕获和操控待测安卓应用的 UI 组件。

UiDevice

UiDevice 代表设备状态。在测试时,可以调用 UiDevice 实例的方法来检查不同属性的状态,如当前的屏幕旋转方向货展示大小。测试代码还能使用 UiDevice 实例来执行设备级的操作,如强制设备横竖屏,按压 d-pad 硬件按钮,或按压主屏幕键和菜单键。
获取 UiDevice 实例,模拟按压主屏幕键的代码如下:

getUiDevice (). pressHome ();

UiSelector

UiSelector 代表一种搜索标准,可以在当前展示界面上查询和获取特定元素的句柄。若找到多于一个的匹配元素,则返回布局层次结构上的 第一个匹配元素作为目标 UiObject。当构造一个 UiSelector 对象时,可以使用链式调用多个属性来缩小查询范围。如无匹配元素,则返回异常 UiAutomatorObjectNotFoundException 。你还可以使用 childSelector() 方法来嵌套多个 Uiselector 实例。例如。下面的代码演示如何制定查询来定位在当前界面的第一个 ListView,然后在返回的 ListView 内定位一个带有 Apps 文本属性的界面元素。

UiObject  appItem  =   new   UiObject ( new   UiSelector () 
. className ( android.widget.ListView ). instance ( 1 ) 
. childSelector ( new   UiSelector (). text ( Apps )));

UiObject

必要时,可以重用测试项目中已经创建的 UiObject 实例。注意,测试用例每次使用 UiObject 实例来点击 UI 元素或查询属性 时,uiautomator 测试框架会搜索当前的界面来寻找匹配。在下面的代码中,uiautomator 测试框架搜索带有 OK 文本属性的 UI 元素。若发 现匹配,并且该元素启用,框架会模拟用户的在该元素上的点击操作。

if ( okButton . exists ()   &&  okButton . isEnabled ()) 
{ 
okButton . click (); 
}

还可以限制搜索在几个特定的类中寻找元素,例如,为发现 Button 类的匹配:

UiObject  cancelButton  =   new   UiObject ( new   UiSelector (). text ( Cancel ) 
. className ( android.widget.Button )); 
UiObject  okButton  =   new   UiObject ( new   UiSelector (). text ( OK ) 
. className ( android.widget.Button ));

UiCollection

UiCollection 代表元素条目的集合,例如音乐专辑中的歌曲或邮箱收件箱列表。类似 UiObject,需要指定 UiSelector 来构造 UiCollection。 用于构造 UiCollection 的 UiSelector 一般搜索容器或包裹器类的界面元素,这样的容器或包裹器类的界面元素包含其他子 UI 元素,例如包 含子元素的布局视图。下面举例说明,下面的代码片段演示如何构造一个 UiCollection 实例,该实例代表一个包含在 FrameLayout 布局中的 视频专辑。

UiCollection  videos  =   new   UiCollection ( new   UiSelector () 
. className ( android.widget.FrameLayout ));

如果视频专辑包含在 LinearLayout 视图下,你能获取视频集合的数目:

int  count  =  videos . getChildCount ( new   UiSelector () 
. className ( android.widget.LinearLayout ));

若想从视频集合中寻找带有文本元素 Cute Baby Laughing 的标签的视频,然后模拟用户在该视频上进行点击,可使用如下代码:

UiObject  video  =  videos . getChildByText ( new   UiSelector () 
. className ( android.widget.LinearLayout ),   Cute Baby Laughing ); 
video . click ();

类似的,还能模拟其他用户操作,如,如想模拟选定一个关联视频的多选框,可以使用如下代码:

UiObject  checkBox  =  video . getChild ( new   UiSelector () 
. className ( android.widget.Checkbox )); 
if (! checkBox . isSelected ())  checkbox . click ();

UiScrollable

UiScrollable 代码可滑动的 UI 元素集合。可以使用 UiScrollable 类来模拟界面的横竖屏的滑动。该技术可以应用于界面元素隐藏在屏幕外,可以通过滑动来展示的情况下。例如,下面的代码演示如何模拟下滑设置按钮,然后点击 About tablet 选项。

UiScrollable  settingsItem  =   new   UiScrollable ( new   UiSelector () 
. className ( android.widget.ListView )); 
UiObject  about  =  settingsItem . getChildByText ( new   UiSelector () 
. className ( android.widget.LinearLayout ),   About  tablet ); 
about . click ()

下面的代码例子演示一个简单的测试用例,它可以用来模拟用户在一个安卓设备上启动设置 Settings 应用。该测试用例模拟用户完成这样的场景的所有步骤,包括打开主屏幕,启动全部应用 All Apps 屏幕,滑动到设置应图标上,点击该图标进入设置应用。

package  com . uia . example . my ;
// Import the uiautomator libraries 
import  com . android . uiautomator . core . UiObject ; 
import  com . android . uiautomator . core . UiObjectNotFoundException ; 
import  com . android . uiautomator . core . UiScrollable ; 
import  com . android . uiautomator . core . UiSelector ; 
import  com . android . uiautomator . testrunner . UiAutomatorTestCase ;
public   class   LaunchSettings   extends   UiAutomatorTestCase   {
public   void  testDemo ()   throws   UiObjectNotFoundException   {
// Simulate a short press on the HOME button. 
//模拟触压一下主屏幕键 
      getUiDevice (). pressHome ();
// We’re now in the home screen. Next, we want to simulate  
// a user bringing up the All Apps screen. 
// If you use the uiautomatorviewer tool to capture a snapshot  
// of the Home screen, notice that the All Apps button’s  
// content-description property has the value “Apps”.  We can  
// use this property to create a UiSelector to find the button. 
//现在在主屏幕上,接下来,需要模拟用户进入全部应用的屏幕上。 
//若你使用uiautomatorviewer工具捕获主屏幕的快照,注意一下”全部应用All Apps“的按钮的content-description属性值为“Apps”. 
//我们使用该属性创建一个UiSelector 对象来定位该按钮。 
       UiObject  allAppsButton  =   new   UiObject ( new   UiSelector () 
. description ( Apps ));
// Simulate a click to bring up the All Apps screen. 
//模拟点击进入全部应用的屏幕 
      allAppsButton . clickAndWaitForNewWindow ();
// In the All Apps screen, the Settings app is located in  
// the Apps tab. To simulate the user bringing up the Apps tab, 
// we create a UiSelector to find a tab with the text  
// label “Apps”. 
//在全部应用的屏幕上,设置应用位于Apps选项卡内。为模拟用户进入该选项卡,我们创建一个UiSelector 对象来定位该带“Apps”文本标签属性的选项卡。 
       UiObject  appsTab  =   new   UiObject ( new   UiSelector () 
. text ( Apps ));
// Simulate a click to enter the Apps tab. 
//模拟点击进入Apps选项卡 
      appsTab . click ();
// Next, in the apps tabs, we can simulate a user swiping until 
// they come to the Settings app icon.  Since the container view  
// is scrollable, we can use a UiScrollable object. 
//接下来在apps选项卡内,我们模拟用户滑动屏幕直至找到设置应用的图标。 
//既然容器视图可以滑动,我们可以使用UiScrollable 对象。 
UiScrollable  appViews  =   new   UiScrollable ( new   UiSelector () 
. scrollable ( true ));
// Set the swiping mode to horizontal (the default is vertical) 
//社会中滑动模式为水平,默认为垂直滑动 
      appViews . setAsHorizontalList ();
// Create a UiSelector to find the Settings app and simulate       
// a user click to launch the app. 
//创建一个UiSelector对象来定位设置应用,模拟用户点击来启动该应用 
       UiObject  settingsApp  =  appViews . getChildByText ( new   UiSelector () 
. className ( android . widget . TextView . class . getName ()), 
Settings ); 
settingsApp . clickAndWaitForNewWindow ();
// Validate that the package name is the expected one 
//验证包名与预期一致 
UiObject  settingsValidation  =   new   UiObject ( new   UiSelector () 
. packageName ( com.android.settings )); 
assertTrue ( Unable to detect Settings , 
settingsValidation . exists ()); 
} 
}
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 6 条回复 时间 点赞
1楼 已删除
2楼 已删除
3楼 已删除

再修改修改。 现在还是没法看。

#3 楼 @tcat 你看看这里:排版说明
发帖的界面里就有这个说明的。

部分觉得翻译不准的内容可以附上原来的单词或短语,但不能是整句话或者直接把整段原文放在中文前面。

如果是译文,麻烦附上原文地址,并注明这是译文。可参考 Android UI Automated Testing(译文)

还有,请添加头像

再修改修改。 现在还是没法看。

一大早 demo 经过微调终于跑起来了,谢谢 tcat 的分享~

头像。。。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册