Android自动化测试四 UiAutomator用法

avatar
作者
猴君
阅读量:0

它是一个Android自动化测试框架,是谷歌在Android4.1版本发布时推出的一款用Java编写的UI测试框架。它只能用于UI也就是黑盒方面的测试。所以UiAutomator只能运行在4.1以后的版本中。其最大的特点就是可以跨进程操作,我们可以使用uiautomator框架提供的一些方便的API来对安卓应用进行一系列的自动化测试操作,如点击、滑动、键盘输入、长按以及常用的断言方法等。可以替代以前繁琐的手工测试。

下面总结一下该框架的几个优点:

  1. Google自家推出的,其稳定性和后续的维护更新可以得到保障,运行时也有更多的权限。
  2. 可以跨进程操作,这点比起其它基于instrumentation框架的自动化工具如Robotium是无法直接做到的。
  3. 运行速度快。
    缺点:
  4. 不支持Android4.1以下的版本。
  5. 不支持Webview,所以一般无法对浏览器应用进行测试。
UiAutomator 框架原理分析:

首先,UiAutomator是Google参考微软的UiAutomation提供的一套用在Android上的自动化测试框架。基于Android AccessilibilityService提供。那么至于什么是AccessilibilityService,在这里简单介绍下:Android AccessilibilityService,是一个可访问服务,它是一个为增强用户界面并帮助残疾用户的应用程序,或者用户可能无法完全与设备的交互。举个简单的例子,假如一个用户在开车。那么用户就有可能需要添加额外的或者替代的用户反馈方式。其应用方式一般有两种:

第一种方法是:UiAutomatorView + monkey。它与hierachyview + monkey差不多。其区别是:UiAutomatorView通过ADB向设备侧发送一个dump命令,而不是建立一个socket,下载一个包含当前界面控件布局信息的xml文件。相比较hierachyview下载的内容而言,该文件小很多。因此,从效率上讲,这种方法比第一种应用模式快很多。

第二种方法是: 直接调用UiAutomator框架对外提供的API,主要有UiDevice、UiSelector、UiObject和 UiScrollable等。其原理与第一种方式即HierachyView + Monkey差不多。其过程大致是:首先,UiAutomator测试框架通过Accessibilityservice,获取当前窗口的控件层次关系及属性信息,并查找到目标控件。若是点击事件,则计算出该控件的中心点坐标。其次,UiAutomator通过 InputManager.getInstance().injectInputEvent隐藏接口来注入用户事件(点击、输入类操作),从而实现跨进程自动化的目的。

UiAutomatorTestCase :这个类是继承自Junit TestCase (Junit),对外提供setup、teardown等,以便初始化用例、清除环境等。所以我们在编写的UiAutomator 的脚本时一般都要继承这个类,这样就可以直接使用它的一些方法和Junit单元测试框架中的Assert断言机制。

UIAutomator2.0

We’re pleased to announce the release of UIAutomator 2.0! This version is a significant update from the previous release. Most importantly, UI Automator is now based on Android Instrumentation and you can build and run tests with the ‘./gradlew connectedCheck’ command.

UiAutomator2.0的jar包并不是在以前SDK/platforms/android-19/下。现在我们要这么做

  1. 通过Android SDK Manager中的 Android Support Repository 项进行安装
  2. 下载下来的jar包的路径为/extras/android/m2repository
  3. 新建一个android项目,编写一个简单的应用
  4. 在build.gradle中配置依赖项:
dependencies {   androidTestCompile 'com.android.support.test:runner:0.3'   // Set this dependency to use JUnit 4 rules   androidTestCompile 'com.android.support.test:rules:0.3'   // Set this dependency to build and run Espresso tests   androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2'   // Set this dependency to build and run UI Automator tests   androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1' } 
  1. 设置AndroidJunitRunner为默认的testInstrumentationRunner
android {     defaultConfig {         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"     } } 
  1. 编写测试代码,在androidTest目录下面新建测试类
public class LoginTest extends InstrumentationTestCase {      protected UiDevice device = null;     protected String appName = "magicCard";      public void runApp(String appName) throws UiObjectNotFoundException, RemoteException {         device = UiDevice.getInstance(getInstrumentation());         device.pressHome();         device.waitForWindowUpdate("", 2000);          UiObject2 allAppsButton = device.findObject(By.desc("Apps"));         allAppsButton.click();         device.waitForWindowUpdate("", 2000);          UiScrollable appViews = new UiScrollable(new UiSelector().scrollable(true));         appViews.setAsHorizontalList();          UiObject settingsApp = appViews.getChildByText(new UiSelector().className(TextView.class.getName()), appName);         settingsApp.clickAndWaitForNewWindow();          assertTrue("Unable to detect app", settingsApp != null);     }      @Override     public void setUp() throws RemoteException, UiObjectNotFoundException {         this.runApp(appName);     }      @Override     public void tearDown() throws RemoteException, UiObjectNotFoundException {         //Empty for the moment     }      public void testUS1() {         UiObject2 usernameLabel = device.findObject(By.clazz(TextView.class.getName()).text("Username"));         assertTrue("Username label not found", usernameLabel != null);     } } 

基于Instrument的方便一点就是不需要remote debug的方式进行调试。并且做参数化之类的也方便了很多。
2.0不用再继承UiAutomatorTestCase,但却需要继承InstrumentationTestCase。

获取设备的方式也变化了,UiDevice.getInstance(getInstrumentation()) 这才是正确的使用方法。之前常用的两种方式都不再可行。

可以通过如下的adb命令调用

adb shell am instrument -w -r   -e debug false -e class com.cxq.uiautomatordemo.UiTest com.cxq.uiautomatordemo.test/android.test.InstrumentationTestRunner 

在dependencies中用到了compile、testCompile、androidTestCompile三种依赖方式,让我们来看看他们有什么区别:

compile:参与编译,并且会打包到debug/release apk中。
testCompile:只参与单元测试编译,不会打包到debug/release apk包中,不需要设备支持。
androidTestCompile:只参与UI测试编译,不会打包到debug/release apk包中,需要设备支持。

除此之外还有Provided、APK、Debug compile和Release compile:

Provided:只参与编译,不会打包到debug/release apk中。
APK:不参与编译,只会打包到debug/release apk中。
Debug compile:只参与debug编译,只会打包到debug apk中。
Release compile:只参与release编译,只会打包到release apk中。

UIAutomator1.0
  1. 新建Java工程
  2. 导入lib包 android.jar 和 uiautomator.jar ,选中点击右键Add to buildPath
  3. 新建测试类demo
 public class Demo extends UiAutomatorTestCase{} 
  1. 写测试方法A,B,C(testcase)
  2. 编译运行:
    5.1. <android-sdk>/tools/android create uitest-project -n <name> -t 1 -p <path>
    说明一下各个参数的作用,如果已经将android sdk的路径配置到了系统的path中,输入命令“android create uitest-project”就可以查看到相应的帮助
  • -n --name : Project name. 就是在eclipse中创建的项目的名字。
  • -t --target : Target ID of the new project. [required] 这个id是本机上android targets的id,可以通过命令 “android list”来查询,得到结果,选择android-17以上版本前面所对应的id,运行完成后,工作空间下生成文件build.xml

5.2. 修改build.xml 将help改为build

<?xml version="1.0" encoding="UTF-8"?>             <project name="demo1" default="build">         

5.3.在build.xml上点击右键,选择“Run As” -> “Ant Build”,编译成功,在工作空间bin下生成一个jar包demo.jar

5.4. adb push demo.jar /data/local/tmp/

5.5. adb shell uiautomator runtest demo.jar -c A -c B -c C (可指定多个testcase,不指定则运行所有)

uiautomator的help帮助:
支持三个子命令:rutest/dump/events

  • runtest命令-c指定要测试的class文件,用逗号分开,没有指定的话默认执行测试脚本jar包的所有测试类.注意用户可以以格式 c l a s s / class/ class/method来指定只是测试该class的某一个指定的方法
  • runtest命令-e参数可以指定是否开启debug模式
  • runtest命令-e参数可以指定test runner,不指定就使用系统默认。我自己从来没有指定过
  • runtest命令-e参数还可以通过键值对来指定传递给测试类的参数

UiAutomator2改进
1. 基于 Instrumentation,可以获取应用Context,使用 Android服务及接口
2. 基于 Junit4,测试用例无需继承于任何父类,方法名不限,使用注解 Annotation进行
3. UI执行效率比 1.0 快,测试执行可使用AndroidJunit 方式及gradle 方式
4. API 更新,新增UiObject2、Until、By、BySelector等:APIFor UI Automator

5. Log 输出变更,以往使用System.out.print输出流回显至执行端,2.0 输出至Logcat

AndroidJUnitRunner
AndroidJUnitRunner
InstrumentationTestRunner
Fundamentals of Testing
UI Automator
androidx.test
Test UI for multiple apps
Instrumentation

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!