UI Testing 翻译

除了针对 Android 应用程序中的组件(诸如:Activty,Service,content provider)进行单元测试以外,在运行时对其用户接口(UI)的行为进行测试也很重要。UI 测似确保应用程序有正确的的 UI 输出来响应用户一系列的操做,好比一个按键输入或者按工具条,菜单,对话框,图片和其它 UI 操做。html

功能测试或者黑盒 UI 测试并不须要测试人员知道应用的内部实现细节,只需知道当用户执行某些操做或者进行某种输入时的输出便可。这种方法有利于分离团队中测试人员和开发人员的职责。java

普通的 UI 测试方法就是手工运行测试并验证应用程序的行为是否符合预期。可是这种方法既沉闷又耗时还容易出现偏差。更高效更可靠的方法是用测试框架软件进行 UI 自动化测试。自动化测试建立代码来执行测试任务(test case),测试任务覆盖各类使用场景,这样测试框架就能够以一种可重复的方式自动运行这些 test case。android

Overview程序员


Android SDK 提供了下面两个工具,来对你的应用程序进行自动化功能测试:shell

  • uiautomatorviewer - 一个用来对应用程序中组件进行扫描和分析的工具。
  • uiautomator - 一个 java 库,其中包含了用于建立自定义 UI 功能测试的 API,和一个用来自动运行测试的运行引擎。

使用这两个工具必须安装下面两个版本的 Android 开发工具:app

  • Android SDK Tools,Revision 21 or higher
  • Android SDK Platform, API 16 or higher

Workflow for the the uiautomator testing framework框架

  1. 下面是 UI 自动化测试的简化流程:
  2. 把待测程序安装到设备上,对应用的 UI 组件进行分析,并确保待测应用程序能够被自动化测试框架访问。
  3. 建立自动化测试来模拟用户和应用之间的一系列交互。
  4. 编译 test case 并打包为 jar 文件,而后安装到待测应用所在的测试设备上。
  5. 运行测试并查看测试结果
  6. 修正测试中发现的 bug 和 不足之处。

Analyzing Your Application’s UIide


在开始写 test case 以前,这有助于咱们熟悉待测应用的 UI 组件(包括 View 和控制)。对于链接开发电脑上的任何 Android 设备,咱们能够用 uiautomatorviewer 工具对其前台 UI 进行截屏。该工具提供一个方便的可视化界面,用于查看其布局层次以及 View 的属性。利用这些信息,咱们接下来就能够建立 uiautomator 测试代码了。函数

UIAutomatorViewer

 

对待测应用程序的 UI 组件进行分析:工具

1.链接 Android 设备和开发电脑。

2.打开命令行窗口并到 <android-sdk>/tools/ 目录下

3.用下面命令运行该工具:

$ uiautomatorviewer

4.点击 uiautomatorviewer 图形界面上的 Device Screenshot 按钮截屏用于分析。

注意:若是你的电脑上连了多个设备,能够经过设置 ANDROID_SERIAL 环境变量来区分它们:

a.用下面命令查看链接设备的 serial numbers:

$ adb devices

b.经过设置 ANDROID_SEIAL 来选择一个设备用于测试:

Windows:

set ANDROID_SERIAL=<device serial number>

UNIX:

export ANDROID_SERIAL=<device serial number>

若是你只连了一个设备就不须要设置该值。

5.查看应用程序总 UI 属性:

  • 在左边的面板中移动鼠标,uiautomatorviewer 就能识别这些组件,而后你就能够看到相应 UI 组件的属性。组件的属性显示在右下角的面板中,布局层次信息列于右上角的面板中。
  • 点击 Toggle NAF Nodes 按钮查看 uiautomator 测试框架不能访问的 UI 组件,可能这些组件只有一部分属性是可访问的。

Preparing to Test


在开始使用 uiautomator 测试框架以前,须要完成下面的准备工做:

Load the application to a device

若是你正在阅读该文档,极可能待测  Android 应用程序还没有发布。若是你有 apk 文件的拷贝,就能够经过 adb 工具把它安装到测试设备上去,如何用 adb 工具安装 APK 文件,请参考 adb 文档。

Identify the application’s UI components

在写 uiatomator 测试以前,首先要识别待测应用程序的 UI 组件。一般优秀应用的 UI 组件是可见的而且能够和用户交互的。UI 组件应该有可见的 text 标签或者 android:contentDescription 属性,或者二者兼具。

咱们能够用 uiautomatorviewer 工具方便地查看待测应用中可见的屏幕对象(UI 组件)。至于如何经过该工具来分析一个应用程序的屏幕信息,请参考 Analyzing Your Application’s UI 部分。关于 Android 提供了那些经常使用的 UI 组件,请参考 User Interface

Ensure that the application is accessible

这一步,是由于 uiautomator 工具运行你的 UI 功能测试代码依赖于 Android 框架支持辅助功能的特性。要使用 uiautomator 工具,至少应该知足一下条件:

  • 使用 android:contentDescription 属性对 ImageButton, ImangeView, CheckBox 以及其它空间设置标签。
  • 对于 EditText 使用 android:hint 属性而不是 content decription 。
  • Associate an android:hint attribute with any graphical icons used by controls that provide feedback to the user (for example, status or state information).
  • 确保全部的可操做元素均可以经过方向控制器访问,好比轨迹球或者方向键。
  • 经过 uiautomatorviewer 工具来确保 UI 元素能够被测试框架访问。咱们也能够用打开诸如 TalkBack 和 Explore by Touch 这写辅助服务来测试,只经过方向控制来测试咱们的应用程序。

关于实现、测试可访问性的更多信息,请参考 Making Applications Accessible

通常状况下,经由 View 和 ViewGroup 类,Android 程序员能够轻易对辅助功能进行支持。可是有些应用使用自定义 view 组件以提供更好的用户体验。而这些自定义组件并无从标注 的 Android UI 组件那里继承到对辅助功能的支持。若是你的应用程序属于这种状况,请经过实现 AccessibilityNodeProvider 类来确保 Android 的辅助服务能够访问自定义 UI 组件。关于如何使自定义控件支持辅助功能,请参考 Making Applications Accessible

Configure your development environment

若是你用 Eclipse 作开发,Android SDK 另外提供了工具来帮助你编写 uiautomator test case 并打包 jar 文件。要设置 Eclipse 以使用这些工具,须要建立一个包含 uiautomator 客户端库的工程,该库通常和 Android SDK 库在一块儿。配置 Eclipse:

  1. 在 Eclipse 中建立一个 Java 工程并给该工程取一个名字,该名字和你即将建立的测试相关(例如:MyAppNameTests)。后面就是在该工程中建立 test case,具体建立什么样的 test case 取决于什么样的待测应用。
  2. 在 Project Explorer 视图中,右键点击刚建立的新工程,而后选择 Properties > Java Build Path,接下来:

a. 点击 Add Library > JUit,而后选择 JUnit3。

b. 点击 Add External JARs… 进入 SDK 目录,在 platforms 目录下,选择最新版本的 SDK目录,并选择 uiautomator.jar 和 android.jar 文件。

若是你不使用 Eclipse 作开发环境,请确保你的 Java class path 包括了 <android-sdk>/platforms/<sdk> 目录下的 uiautomator.jar 和 android.jar 文件。

这些准备工做完成后,立刻就能够建立 uiautomator 测试了。

Creating uiautomator Tests


要构建一个能够在 uiautomator 框架中运行的测试,首选要建立一个继承自 UiAutomatorTestCase 的类。在 Eclipse 中这个 test case 文件属于工程的 src 目录。而后,会把这个 test case 构建成一个 JAR 文件,最后把这个 JAR 文件复制到测试设备中。这个 JAR 文件并非一个 APK 文件,而且和待测应用是分离的。

由于 UiAutomatorTestCase 类继承自 junit.framework.TestCase,因此你能够用 JUnit 的 Assert 类来测试待测应用中的 UI 组件,看是否返回指望结果。要学习更多的 JUnit 知识,你能够阅读 junit.org 主页中的文档。

test case 的首要任务是将要访问安装了待测应用程序的设备。先对设备的 Home screen 作测试来练练手也是一个不错的选择。对于 Home Screen(或者待测应用的其它位置),你能够用 uiautomator 提供的 API 来模拟用户的操做对特定的 UI 组件进行测试。至于如何组织一个 uiautomator test case 请看 sample test case 部分。

uiautomator API

uiautomator API 在 <android-sdk>/platforms/ uiautomator.jar 文件中,该 API 中包含如下几个关键类,经过这些类咱们能够捕获、操做待测应用中的 UI 组件:

UiDevice

表明了设备的状态。在测试代码中,能够调用 UiDevice 实例中的函数来检测设备的各类属性状态,例如当前的屏幕的方向或者尺寸。也能够经过  UiDevice 实例来执行设备层次的操做,好比强制改变设备的方向,按下 d-pad 物理按键或者 Home 建和菜单按钮。

下面代码就是获取 UiDevice 实例,而后按下 Home 键:

getUiDevice().pressHome();

UiSelector

表示一个在当前显示界面查询、获取特定组件的搜素条件。若是找到多个匹配组件,那么就返回布局层次中的第一个匹配组件,返回的是一个 UIObject 对象。构造一个 UiSelector 对象时,能够组合多个属性使搜索更精确。若是一个也没找到,就会抛出一个 UiAutomatorObjectNotFoundException 异常。也能够用 childSelector() 函数来嵌套多个 UiSelector 实例。例如,下面的示例代码就展现了如何设定一个搜索条件,在当前显示界面中找到第一个 ListView,而后在这个 ListView 中搜索一个 text 属性为 “Apps”的 UI 组件。

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

UiObject

表明一个 UI 组件。建立 一个 UiObject 实例时经过一个 UiSelector 对象来搜索对应的 UI 组件。

下面的示例代码展现了如何建立 UiObject 对象,这两个对象表示应用程序中的一个 Cancel 按钮和一个 OK 按钮。

UiObject cancelButton = new UiObject(new UiSelector().text("Cancel")); UiObject okButton = new UiObject(new UiSelector().text("OK"));

若是须要,你能够在测试程序的其它地方重用已经建立的 UiObject 实例。要注意的是,在测试代码中你每次用一个 UiObject 实例对一个 UI 组件进行点击操做或者查询其属性,uiautomator 测试框架都会在当前显示界面进行一次搜索。

在下面的示例代码中,uiautomator 测试框架会先搜索 text 属性为 “OK”的 UI 组件,若是存在而且是 enable 的,那么测试框架就会模拟用户对该组件进行点击操做。

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,UiSelector 用于搜索多个子控件的容器(例如:一个包含子控件的 Layout)。例如,下面的代码片断展现了如何建立一个表明一个视频专辑的 UiCollection,该专辑显示在一个 FrameLayout 中:

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

若是这些视频都显示在一个 LinearLayout 中,你又想获取这些视频的个数:

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

若是你要从中找出一个 text 属性为 “Cute Baby Laughting”的视频,并模拟用户去点击它:

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

对于这个 UI 对象上你一样能够模拟其它的用户操做。例如,你能够模拟选择一个与某一视频线关联的 checkbox:

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

UiScollable

表明一个可滚动的 UI 组件集合。你能够用 UiScrollable 来模拟 UI 组件的垂直或者水平滚动。当一个 UI 组件显示在屏幕之外,你须要滚动才能看到它,这时候这个技术就颇有用。

例以下面的示例代码演示如何模拟向下滚动设置菜单并点击一个 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()

关于这些 API 的更多信息请参考 uiautomator

A sample uiautomator test case

下面的示例代码是一个简单的 test case,它模拟用户在一个通用 Android 设备上进行设置应用程序的操做。该 test case 模拟用户执行这个任务一般会作的全部操做,包括打开 Home Screen,打开 All Apps Screen,滚动找到 Settings app 的图标,而后点击这个图标进入设置界面。

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 { // 模拟点击 HOME 按钮.
 getUiDevice().pressHome(); // 如今在 Home Sceen. 接下来咱们模拟用户进入 All Apps 屏 // 若是用 uiautomatorviewer 工具对 Home Screen 进行截图分析// 就会发现 All Apps 按钮的 content-description 属性的值是 “Apps” // 咱们能够用这个属性值建立一个 UiSelector 来找到这个按钮。
      UiObject allAppsButton = new UiObject(new UiSelector() .description("Apps")); // 模拟进入 All Apps 屏
 allAppsButton.clickAndWaitForNewWindow(); // 设置按钮在 All Apps 屏的 “Apps tab” 中。咱们建立一个 UiSelector 找到 // text 属性是 “Apps” 的 tab ,而后模拟用户点击进入 Apps tab。
      UiObject appsTab = new UiObject(new UiSelector() .text("Apps")); // 模拟点击进入 Apps tab
 appsTab.click(); // 接下来在 Apps tab 中模拟用户滑动屏幕找到设置程序的图标。 // 由于这个 Apps tab 是能够滑动的,因此咱们能够用一个 UiScrollable 对象。
      UiScrollable appViews = new UiScrollable(new UiSelector() .scrollable(true)); // 设置为水平滑动模式(模式是垂直滑动)
 appViews.setAsHorizontalList(); // 建立一个 UiSelector 找到设置按钮, // 而后模拟用户点击加载这个程序 
      UiObject settingsApp = appViews.getChildByText(new UiSelector() .className(android.widget.TextView.class.getName()), "Settings"); settingsApp.clickAndWaitForNewWindow(); // 验证它的 package name 是否符合预期。
      UiObject settingsValidation = new UiObject(new UiSelector() .packageName("com.android.settings")); assertTrue("Unable to detect Settings", settingsValidation.exists()); } }

Building and Deploying Your uiautomator Tests


完成测试代码以后,根据下面步骤来 build 并把 JAR 文件部署到测试机上:

  • 建立 build 配置文件用来生成 JAR。打开终端而后运行下面命令来生成 build 配置文件:
<android-sdk>/tools/android create uitest-project -n <name> -t 1 -p <path>

<name> 是包含 uiautomator 测试源代码的工程名字,<path> 是项目文件夹的路径。

  • 从命令行设置 ANDORID_HOME 变量:

Windows:

set ANDROID_HOME=<path_to_your_sdk>

UNIX:

export ANDROID_HOME=<path_to_your_sdk>
  • 进入工程文件夹,build.xml 文件就在这里。而后 build 生成 JAR 文件。
ant build
  • 用 adb push 命令把生成的 JAR 文件部署到测试机
adb push <path_to_output_jar> /data/local/tmp/
下面是一个例子
adb push ~/dev/workspace/LaunchSettings/bin/LaunchSettings.jar /data/local/tmp/

Running uiautomator Tests


下面的例子是展现如何运行 LaunchSettings.jar 测试代码。该测试位于 com.uia.example.my 包中:

adb shell uiautomator runtest LaunchSettings.jar -c com.uia.example.my.LaunchSettings

关于 uiautomator 的语法、命令、设置的详细信息请参考 uiautomator

Best Practices


下面是一些用 uiautomator 框架进行 UI 功能测试的最佳实践:

  • 一样的 UI 功能,要在尽量多的设备上进行测试(例如不一样屏幕密度的设备)。
  • 同时, 也应该测试一些常规的场景,例如,来电话的时候,断网的状况,切换其它应用的状况。
相关文章
相关标签/搜索