Android自动化测试(UiAutomator)

来源:互联网 发布:keyerror python 编辑:程序博客网 时间:2024/05/16 02:01

一、一个BUG引发的问题


    如果研发过程中有一个BUG:“不断的切换手机语言出现花屏现象”。这个问题我们如何验证呢?我想,最好的方式应该是自动化测试。
    那么,自动化测试可以完成哪些任务呢?
    简单的说,那些重复性的测试工作,都可以交给自动化完成:
        1、设置手机的语言
        2、添加、删除、收藏联系人
        3、拨号、挂断
        4、甚至发送短信、收藏短信

    如果需要上面的功能,那么就开始自动化之旅吧。


二、Android自动化测试简单介绍


    Android自动化测试主要分为Monkeyrunner、Rubotium、UiAutomator、Monkey(在我看来这个不算)等。主要特点:
    1、Monkeyrunner:优点:操作最为简单,可以录制测试脚本,可视化操作;缺点:主要生成坐标的自动化操作,移植性不强,功能最为局限;
    2、Rubotium:主要针对某一个APK进行自动化测试,APK可以有源码,也可以没有源码,功能强大;缺点是针对APK操作,而且需要对APK重新签名(有工具),因此操作相对复杂;
    3、UiAutomator:优点:可以对所有操作进行自动化,操作简单;缺点:Android版本需要高于4.0,无法根据控件ID操作,相对来说功能较为局限,但也够用了;
    4、Monkey:准确来说,这不算是自动化测试,因为其只能产生随机的事件,无法按照既定的步骤操作;
    由上面介绍可以有这样的结论:测试某个APK,可以选择Rubotium;测试过程可能涉及多个APK,选择UiAutomator;一些简单的测试,选择Monkeyrunner;

    本文主要介绍UiAutomator的使用方法。


三、环境搭建


3.1、必备条件:

    1、JDK
    2、SDK(API高于15)
    3、Eclipse(安装ADT插件)
    4、ANT(用于编译生成jar)

3.2、简要步骤:

    1、安装JDK并添加环境变量。
        安装后,一定要通过JAVA_HOME的方式添加环境变量,即先建立JAVA_HOME变量,然后在path中添加%JAVA_HOME%\bin;
    2、添加SDK环境变量。
        一定要先建立ANDROID_HOME,然后把%ANDROID_HOME%\tools添加到path中;
    3、安装Eclipse,并安装ADT插件。
    4、安装ANT工具,并添加环境变量。

        同样一定要先建立%ANT_HOME%变量,然后在path中添加%ANT_HOME%\bin


四、详细操作


4.1、建立工程

    用Eclipse新建Java Project,注意,不是Android Project!

4.2、添加JUnit库

    


4.3、添加Android库

    找到路径Android-sdk\platforms\android-17\下面的android.jar和uiautomator.jar添加进来:
    
    所有库添加完应该是这个样子:

    


4.4、在src中添加包,然后添加class文件

    文件内容为:

[java] view plaincopy
  1. package com;  
  2. import com.android.uiautomator.core.UiObject;  
  3. import com.android.uiautomator.core.UiObjectNotFoundException;  
  4. import com.android.uiautomator.core.UiScrollable;  
  5. import com.android.uiautomator.core.UiSelector;  
  6. import com.android.uiautomator.testrunner.UiAutomatorTestCase;  
  7.   
  8. public class Runner extends UiAutomatorTestCase {  
  9.   
  10.     public void testDemo() throws UiObjectNotFoundException {  
  11.         getUiDevice().pressHome();  
  12.         // 进入设置菜单  
  13.         UiObject settingApp = new UiObject(new UiSelector().text("Settings"));  
  14.         settingApp.click();  
  15.         //休眠3秒  
  16.         try {  
  17.             Thread.sleep(3000);  
  18.         } catch (InterruptedException e1) {  
  19.             // TODO Auto-generated catch block  
  20.             e1.printStackTrace();  
  21.         }  
  22.         // 进入语言和输入法设置  
  23.         UiScrollable settingItems = new UiScrollable( new UiSelector().scrollable(true));  
  24.   
  25.         UiObject languageAndInputItem = settingItems.getChildByText(  
  26.                 new UiSelector().text("Language & input"), "Language & input"true);  
  27.         languageAndInputItem.clickAndWaitForNewWindow();  
  28.           
  29.     }  
  30. }  
    上面工程路径在e:\workspace\AutoRunner,类全名为com.Runner,至于具体的作用我们现在不去关心。

4.5、找到SDK ID

    CMD进入\Android-sdk\tools\目录下,运行命令:
    android list
    查看API大于15的SDK的ID值,当前是6;
    

4.6、创建build文件

    仍然在\Android-sdk\tools\目录下,运行命令:
    android create uitest-project -n <name> -t <android-sdk-ID> -p <path>
    比如:
    android create uitest-project -n AutoRunner -t 6 -p e:\workspace\AutoRunner
    上面的name就是将来生成的jar包的名字,可以自己定义,android-sdk-ID就是上面看到的6;path是Eclipse新建的工程的路径;运行命令后,将会在工程的根目录下生成build.xml文件。如果没生成,检查上面的步骤。

4.7、编译生成jar

    CMD进入项目的工程目录,然后运行ant build,将使用ant编译生成jar,成功将会提示:
    
    然后会在bin目录下生成jar文件。

4.8、push并运行jar

    adb push <jar文件路径> data/local/tmp
    adb shell uiautomator runtest <jar文件名> -c <工程中的类名,包含包名>
    比如:
    adb push e:\workspace\AutoRunner\bin\AutoRunner.jar data/local/tmp
    adb shell uiautomator runtest AutoRunner.jar -c com.Runner

    然后就能看到手机会按照Runner中的步骤自动执行。具体效果就是,进入设置菜单,然后再进入“语言和输入法”菜单


五、代码分析


    我们从几个最重要的对象来介绍。

5.1、UiDevice对象

    getUiDevice()的方法可以得到一个UiDevice的对象,通过这个对象可以完成一些针对设备的动作:
    click(int x, int y)
    ----在(x,y)表示的像素地方点击
    pressBack()
    pressDelete()
    pressEnter()
    pressHome()
    pressMenu()
    pressSearch()
    ----点击相应的按键
    wakeUp()
    ----当手机处于灭屏状态时,唤醒屏幕,并解锁。
    swipe(startX, startY, endX, endY, steps)
    ----在手机上滑动,从(startX,startY)到(endX,endY)。steps表示滑动的这个距离分为几步完成,数目越少,滑动幅度越大。
    setOrientationLeft()
    setOrientationRight()
    ----将手机向相应方向旋转。
    setOrientationNatural()
    ----将手机旋转状态回归正常。

5.2、UiSelector对象

    这个对象可以理解为一种条件对象,描述的是一种条件,经常配合UiObject使用,可以得到某个(某些)符合条件的控件对象。
    checked(boolean val)
    ----描述一种check状态为val的关系。
    className(className)
    ----描述一种类名为className的对象关系
    clickable(boolean val)
    ----与checked类似,描述clickable状态为val的关系
    description(desc)
    ----不解释
    descriptionContains(desc)
    ----与description类似
    focusable(boolean val)
    ----与checked类似
    index(index)
    ----用当前对象在父对象集中的索引作为描述
    packageName(String name)
    ----用包名作为条件描述
    selected(val)
    ----描述一种选择关系
    text(text)
    ----最为常用的一种关系,用控件上的文本即可找到当前控件,需要注意,所有使用text属性找到的控件,必须是英文的。也就是说,不支持通过中文查找控件!
    textContains(text)
    ----与text类似
    textStartsWith(text)
    ----与text类似

5.3、UiObject对象

    这个对象可以理解为控件的对象。 一般一个UiObject对象可以通过一下形式得到:
    UiObject mItem = new UiObject(new UiSelector().text("English"));
    也就是配合一个UiSelector就可以得到一个控件。
    click()
    ----点击控件
    clickAndWaitForNewWindow()
    ----点击某个控件,并等待窗口刷新
    longClick()
    ----长按
    clearTextField()
    ----清除文本,主要针对编辑框
    getChildCount()
    ----这个方法可以看出,其实UiObject也可以是一个控件的集合
    getPackageName()
    ----得到控件的包名
    getSelector()
    ----得到当前控件的选择条件
    getText()
    ----得到控件上的Text
    isCheckable()
    isChecked()
    isClickable()
    isLongClickable()
    isScrollable()
    isScrollable()
    isSelected()
    ----判断是否具备某个属性

5.4、UiCollection对象

    这个对象可以理解为一个对象的集合。因为UiSelector描述后得到的有可能是多个满足条件的控件集合,因此可以用来生成UiCollection:
    UiCollection mUiCollection = new UiCollection(new UiSelector().text("Settings"));
    getChild(selector)
    ----从集合中再次通过UiSelector选择一个UiObject对象
    getChildByDescription(childPattern, text)
    ----从一个匹配模式中再次以text为条件选择UiObject
    getChildByText(childPattern, text)
    ----与上面类似。
    getChildCount()
    ----得到当前集合中控件的个数

5.5、UiScrollable对象

    UiScrollable可以生成一个滚动动作的对象,其最大的作用就是可以实现滚动的查找某个元素。比如在“设置”菜单中,“语言和输入法”这个菜单比较靠下,需要滚动后才可以看到(找到),因此就用上了UiScrollable:

[java] view plaincopy
  1. UiScrollable settingItems = new UiScrollable( new UiSelector().scrollable(true));  
  2. UiObject languageAndInputItem = settingItems.getChildByText(  
  3. new UiSelector().text("Language & input"), "Language & input",  
  4. true);  
    上面的形式就可以在滚动中查找显示有“Language & input”的控件,也就是“语言和输入法”的设置项。

5.6、等待操作和添加Log的方法

    如果是对于一个标准的UiObject对象,可以通过clickAndWaitForNewWindow的方法在点击之后主动等待一段事件,但是如果需要额外的等待一段时间,特别对于getUiDevice().pressHome();这种操作,可能需要很长的事件去为下一步操作获取更多的事件,此时我们可以使用线程的sleep方法去实现:

[java] view plaincopy
  1. //等待3秒  
  2. try {  
  3.     Thread.sleep(3000);  
  4. catch (InterruptedException e1) {  
  5.     e1.printStackTrace();  
  6. }  

    而添加Log的方法也可以通过Java标准的println来实现:
    System.out.println("This used to print some log!!!" + setLanItem.getText());
    以上Log将会在jar被运行时通过CMD窗口打印出来。


六、一个相对完整的测试case


    下面就用一个相对连贯的测试用例来串一下上面的知识点,这个case用例要做的就是进入系统设置菜单,然后选择“语言和输入法”菜单,然后进入“语言设置”菜单,然后在第一项上点击,把当前语言设置为“简体中文”:

[java] view plaincopy
  1. public void setChineseLan() throws UiObjectNotFoundException {  
  2.     //进入操作前,先用Home键进入待机界面  
  3.     getUiDevice().pressHome();  
  4.   
  5.   
  6.     //进入“系统设置”菜单。也可以通过点击menu按键来实现  
  7.     UiObject settingApp = new UiObject(new UiSelector().text("Settings"));  
  8.     settingApp.click();  
  9.   
  10.   
  11.     //等待3秒  
  12.     try {  
  13.         Thread.sleep(3000);  
  14.     } catch (InterruptedException e1) {  
  15.         e1.printStackTrace();  
  16.     }  
  17.   
  18.   
  19.     //用滚动的方式查找并进入“语言和输入法设置”菜单  
  20.     UiScrollable settingItems = new UiScrollable(  
  21.             new UiSelector().scrollable(true));  
  22.   
  23.   
  24.     UiObject languageAndInputItem = settingItems.getChildByText(  
  25.             new UiSelector().text("Language & input"), "Language & input",  
  26.             true);  
  27.     languageAndInputItem.clickAndWaitForNewWindow();  
  28.   
  29.   
  30.     //找到“English”的可点击项(因为当前是英文环境)  
  31.     UiObject setLanItem = new UiObject(new UiSelector().text("English"));  
  32.     setLanItem.clickAndWaitForNewWindow();  
  33.   
  34.   
  35.     //Log输出  
  36.     System.out.println("setLanItem-->" + setLanItem.getPackageName());  
  37.   
  38.   
  39.     //由于无法识别中文,因此我们这里使用坐标去选择“简体中文”项  
  40.     getUiDevice().click(350250);  
  41.       
  42.     //点击返回键,回到待机界面  
  43.     getUiDevice().pressBack();  
  44.     getUiDevice().pressBack();  
  45.     getUiDevice().pressBack();  
  46. }   

转自:http://blog.chengyunfeng.com/?p=504


在Android 4.1发布的时候包含了一种新的测试工具–uiautomator,uiautomator是用来做UI测试的。也就是普通的手工测试,点击每个控件元素 看看输出的结果是否符合预期。比如 登陆界面 分别输入正确和错误的用户名密码然后点击登陆按钮看看是否能否登陆以及是否有错误提示等。

功能性或者黑盒UI测试不需要测试人员了解程序如何实现的,只需要验证各种操作的结果是否符合预期即可。这样的测试可以分离团队的开发人员和测试人员。大家各干各的没有太多的交集。

常用的UI测试方式就是人工验证啦,就是测试人员拿着各种手机分别安装要测试的程序然后看看是否能正确完成各种预定的功能。但是这种验证方式是非常耗时间的,每次回归都要全部验证一边,并且还容易出现人为错误。比较高效和可靠的UI测试方式就是自动化测试。自动化UI测试创建测试代码来执行测试任务,各种测试任务分别覆盖不同的使用场景,然后使用测试框架来运行这些测试任务。

uiautomator 就是你的自动化UI测试工具。

概述

Android SDK在4.1中提供了如下工具来支持UI自动化测试:

  • uiautomatorviewer – 一个图形界面工具来扫描和分析应用的UI控件。
  • uiautomator – 一个测试的Java库,包含了创建UI测试的各种API和执行自动化测试的引擎。

要使用该工具,需要满足如下条件:

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

uiautomator 测试工具的工作流程

下面是uiautomator 工作流程概述:

  1. 安装要测试的应用到手机中,分析应用的UI界面元素 并确保被测试应用的各个控件可以被测试工具获取到。
  2. 创建知道测试案例来模拟应用中的用户操作步骤。
  3. 编译测试案例代码为Jar包并复制该Jar包到安装了待测应用的测试手机中。
  4. 运行测试并查看结果
  5. 修改任何发现的bug,然后修复并重新测试。

分析待测应用的UI元素

在开始编写测试案例代码之前,需要熟悉待测应用的UI元素。可以通过uiautomatorviewer 工具来获取应用的界面截图并分析。uiautomatorviewer 工具提供了一个便利的方式来查看UI布局结构,并且可以查看各个控件的相关属性。利用这些信息可以用来创建UI测试代码。

uiautomatorviewer 工具截图

uiautomatorviewer 工具截图

分析待测应用UI界面的步骤如下:

1. 把Android手机连接到电脑上
2. 打开命令行窗口并导航到目录 /tools/
运行如下命令:$ uiautomatorviewer

windows下运行 uiautomatorviewer.bat 命令
3. 点击uiautomatorviewer 工具右上角文件夹按钮旁边的“Device Screenshot”按钮来获取当前 屏幕界面信息。
注意:如果当前电脑连接了多个设备,通过设置ANDROID_SERIAL环境变量来指定要分析的设备。步骤如下:
a.运行如下命令获取连接到电脑的设备序列号
$  adb devices
b.设置ANDROID_SERIAL为需要测试的设备序列号
Windows:set ANDROID_SERIAL=
Unix: export ANDROID_SERIAL=
如果电脑只连接一个设备则无需设置ANDROID_SERIAL 环境变量。

4. 查看待测应用的UI界面元素属性
把鼠标放到uiautomatorviewer工具左边的截图中的控件上来查看该控件的属性。属性显示在右侧界面下方,上方显示当前界面的布局结构。
点击右侧上方的黄三角按钮(Toggle NAF Nodes)来查看不能被uiautomator测试工具访问到的控件。这些控件只设置了有限的属性,所以导致uiautomator无法获取到这些控件。所以你可能很难测试这些控件。这种情况下你可以要求开发者为这些控件添加必要的属性,比如 如果是ImageView或者ImageButton应该添加android:contentDescription属性。

测试准备工作

在开始使用uiautomator 之前需要完成如下准备工作:

把待测应用安装到测试手机(设备)上

当你准备测试的时候,待测的应用可能还没有发布到市场上。但是你应该具有该应用的APK安装文件,你可以通过ADB工具来安装待测应用到手机中,或者通过其他工具来安装Apk。

辨别待测应用UI控件

在开始编写uiautomator测试代码之前,需要先辨别待测应用的UI控件元素。一般而言,优秀的待测应用的UI元素应该是可见的并且用户可以操作的。这些UI元素也应该具有可见的文本标签、android:contentDescription值或者二则兼具。

通过uiautomatorviewer 工具可以查看应用的可见控件。具体使用情况见上面所述。

确保待测应用是可访问的

由于uiautomator 工具依赖Android设备的可访问行来获取UI控件,所以这不是非常重要的。要支持uiautomator 工具需要一下条件:

  • 使用android:contentDescription属性给 ImageButton, ImageView, CheckBox和其他控件设置标签。
  • 使用android:hint 属性来标记EditText 控件,而不是使用里面的文本(文本内容用户是可以修改的)。
  • 对于用来提供操作视觉反馈的UI(文本或者图标),都添加一个android:hint 属性来识别。
  • 确保所有用户可操作的界面元素都可以通过方向控制键选中(例如轨迹球)。
  • 通过uiautomatorviewer 工具来确保所有的UI元素都可以被测试工具访问到。还可以通过“辅助功能”(在设置界面)中的“TalkBack”等服务来测试UI的可访问性。
设置开发环境

如果你使用的是Eclipse(Adt),则Android SDK提供了额外的工具来帮助你编写uiautomator测试代码和打包测试项目。在Eclipse中创建uiautomator测试项目的过程如下:

  1. 创建新的Java项目(注意不是Android项目)。在该项目中来创建测试代码。
  2. 在Project Explorer视图中,右键点击测试项目,选择“ Properties > Java Build Path”,然后选择“Libraries” tab界面。在“Libraries”界面选择“ Add Library > JUnit”来添加JUnit3 库。然后点击“Add External JARs… ”并导航到Android SDK目录。选择platforms目录下面的 uiautomator.jar 和 android.jar文件。
  3. 设置好的build path如下图:
uiautomator项目类路径设置

uiautomator项目类路径设置

如果你不使用Eclipse,则需要确保/platforms/目录中的uiautomator.jar 和 android.jar 位于项目Build path中。

配置好开发环境后就可以开始编写测试代码了。

创建uiautomator 测试案例

uiautomator 测试案例(Test case)需要继承至UiAutomatorTestCase 类。而UiAutomatorTestCase 类继承至junit.framework.TestCase类,所以可以用JUnit的Assert类来比较测试结果。

UI测试的首要任务就是访问测试手机。一般都是从手机的主屏开始测试的。通过uiautomator 提供的API可以从主屏来模拟用户的操作。下面会介绍具体示例。

uiautomator API

uiautomator API在 uiautomator.jar 文件中。这些API分别如下:

UiDevice

代表设备状态。在测试中,可以通过UiDevice实例来检测设备的各种属性,例如当前的屏幕方向以及屏幕尺寸。同时还可以通过UiDevice实例来执行设备级别的操作,例如 把设备设置为横屏或者竖屏、按下Home按键等。

如下是模拟按下Home按键的代码:
getUiDevice().pressHome();

UiSelector

代表一个搜索UI控件的条件。如果发现多个满足条件的控件则会返回第一个控件。返回的结果为UiObject对象。在构造UiSelector的时候可以组合使用多个属性来定位具体的控件。如果没有找到控件则会抛出 UiAutomatorObjectNotFoundException 异常。还可以使用childSelector()函数来嵌套UiSelector 对象。例如,下面的代码演示了如何在当前界面中查找第一个ListView中的带有文本属性为Apps的子控件。

帮助
1
2
3
UiObject appItem = newUiObject(newUiSelector()
.className("android.widget.ListView").instance(1)
.childSelector(newUiSelector().text("Apps")));
UiObject

代表一个UI控件。通过UiSelector来查找UiObject。
如下示例代码演示了如何查找当前显示界面中的取消按钮和确认按钮:

帮助
1
2
UiObject cancelButton = newUiObject(newUiSelector().text("Cancel"));
UiObject okButton = newUiObject(newUiSelector().text("OK"));

查找到的UiObject实例可以在其他测试代码中重用。需要注意的是:每次使用UiObject做操作的时候uiautomator 都会在当前屏幕重新查找该控件。

如下代码uiautomator 工具在当前界面查找文本内容为“OK”的控件。如果存在并且可用则模拟用户点击该控件。

帮助
1
2
3
4
if(okButton.exists() && okButton.isEnabled())
{
okButton.click();
}

还可以限制仅仅查找特定类型的控件。例如 如下代码只查找文本为“Cancel”和“OK”的android.widget.Button类型控件。

帮助
1
2
3
4
UiObject cancelButton = newUiObject(newUiSelector().text("Cancel")
.className("android.widget.Button"));
UiObject okButton = newUiObject(newUiSelector().text("OK")
.className("android.widget.Button"));
UiCollection

代表控件的集合。获取UiCollection的方式和UiObject一样,通过 UiSelector查找。 UiCollection对应Android系统中的ViewGroup以及子控件。
如下代码演示如何通过UiSelector来获取包含视频集合的UiCollection。

帮助
1
2
UiCollection videos = newUiCollection(newUiSelector()
.className("android.widget.FrameLayout"));

如果每个视频是放到LinearLayout中的,则可以通过如下方式获取视频的数目:

帮助
1
2
intcount = videos.getChildCount(newUiSelector()
.className("android.widget.LinearLayout"));

如果需要查找标签为“Cute Baby Laughing”的视频,并点击。则可以通过如下方式:

帮助
1
2
3
UiObject video = videos.getChildByText(newUiSelector()
.className("android.widget.LinearLayout"),"Cute Baby Laughing");
video.click();

同样还可以模拟其他用户操作。例如,模拟选择视频的操作如下:

帮助
1
2
3
UiObject checkBox = video.getChild(newUiSelector()
.className("android.widget.Checkbox"));
if(!checkBox.isSelected()) checkbox.click();
UiScrollable

代表可滚动的控件。可以用UiScrollable来模拟水平或者垂直滚动的UI元素。如果需要操作的元素在屏幕外需要滚动屏幕才能看到的情况下需要使用UiScrollable。

例如,下面的代码显示了如何模拟滚动到“Settings ”菜单并点击“About tablet”菜单的操作。

帮助
1
2
3
4
5
UiScrollable settingsItem = newUiScrollable(newUiSelector()
.className("android.widget.ListView"));
UiObject about = settingsItem.getChildByText(newUiSelector()
.className("android.widget.LinearLayout"),"About tablet");
about.click()

其他API参考uiautomator api文档。

一个简单的uiautomator 测试案例

如下是一个简单的测试案例代码,模拟了点击Home键回到主屏,然后点击所以应用按钮打开所有应用列表,并滚动到时钟应用。打开时钟应用 并选择闹铃界面的第一个闹钟设置,修改该设置的开关。然后返回到时钟界面再进入倒计时界面。

帮助
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
packagecom.uia.example.my;
 
importandroid.widget.ListView;
importandroid.widget.Switch;
 
importcom.android.uiautomator.core.UiObject;
importcom.android.uiautomator.core.UiObjectNotFoundException;
importcom.android.uiautomator.core.UiScrollable;
importcom.android.uiautomator.core.UiSelector;
importcom.android.uiautomator.testrunner.UiAutomatorTestCase;
 
publicclassLaunchSettings extendsUiAutomatorTestCase {
 
    // TODO 重要注意: 在运行该测试代码的时候 需要先把手机语言环境设置为英文。
    publicvoidtestDemo() throwsUiObjectNotFoundException {
 
        // 模拟 HOME 键点击事件
        getUiDevice().pressHome();
 
        // 现在打开了主屏应用,模拟点击所有应用按钮操作来启动所有应用界面。
        // 如果你使用了uiautomatorviewer来查看主屏,则可以发现“所有应用”按钮的
        // content-description 属性为“Apps”。可以使用该属性来找到该按钮。
        UiObject allAppsButton = newUiObject(newUiSelector().description("Apps"));
 
        // 模拟点击所有应用按钮,并等待所有应用界面起来
        allAppsButton.clickAndWaitForNewWindow();
 
        // 在所有应用界面,时钟应用位于Apps tab界面中。下面模拟用户点击Apps tab操作。
        // 找到 Apps tab 按钮
        UiObject appsTab = newUiObject(newUiSelector().text("Apps"));
 
        // 模拟点击 Apps tab.
        appsTab.click();
 
        // 然后在 Apps tab界面,模拟用户滑动到时钟应用的操作。
        // 由于Apps界面是可以滚动的,所有用
        // UiScrollable 对象.
        UiScrollable appViews = newUiScrollable(newUiSelector().scrollable(true));
 
        // 设置滚动模式为水平滚动(默认为垂直滚动)
        appViews.setAsHorizontalList();
 
        if(allAppsButton.exists() && allAppsButton.isEnabled()) {
            // allAppsButton在当前界面已经不可见了 所以这里不会执行
            allAppsButton.click();
        }
        // 查找时钟应用并点击
        UiObject settingsApp = appViews.getChildByText(
                newUiSelector().className(android.widget.TextView.class.getName()),"Clock");
        settingsApp.clickAndWaitForNewWindow();
 
        // 验证当前显示 的应用包名为时钟
 
        UiObject settingsValidation = newUiObject(newUiSelector().packageName("com.google.android.deskclock"));
        // 如果不存在则出错提示
        assertTrue("Unable to detect Clock", settingsValidation.exists());
 
        // 模拟点击时间tab
        UiObject clock = newUiObject(newUiSelector().description("Clock"));
        clock.clickAndWaitForNewWindow();
        // 模拟点击下方的闹钟图标
        UiObject alarms = newUiObject(newUiSelector().description("Alarms"));
        alarms.clickAndWaitForNewWindow();
 
        UiScrollable list = newUiScrollable(newUiSelector().className(ListView.class.getName()));
        if(list.getChildCount() > 0) {
            UiObject listIndex0 = list.getChild(newUiSelector().index(0));
            UiObject switchBtn = listIndex0.getChild(newUiSelector().className(Switch.class.getName()));
 
            booleanisChecked = switchBtn.isChecked();
 
            switchBtn.click();
        }
        // 模拟点击返回键
        getUiDevice().pressBack();
 
        UiObject timer = newUiObject(newUiSelector().description("Timer"));
        timer.clickAndWaitForNewWindow();
 
    }
}
打包测试代码并在测试机上运行

如下步骤打包测试代码并在测试机运行的步骤:

1.创建打包测试代码的Build脚本。通过如下命令来生成Build脚本:

<android-sdk>/tools/android create uitest-project -n <name> -t 1 -p <path>
<name>是包含测试代码的项目名称,<path>是包含测试代码的项目文件路径。-t后面的1是Android sdk版本id。

注意: 在创建Build脚本之前,已经创建好了测试项目并编写好了测试代码。只不过该测试项目还没有包含打包脚本所以无法打包运行。在创建Build脚本的时候,<name>属性就是测试项目的名称、<path>就是已经创建的测试项目在电脑中的文件夹路径。 如果电脑上安装了多个版本的Android sdk,则需要运行/tools/android list target 来查看每个SDK的id。选择4.1以上的id即可。

2. 设置ANDROID_HOME 环境变量。

Windows:set ANDROID_HOME=

Unix:export ANDROID_HOME=

3. 打开命令行创建,导航到第一步中的目录中,运行 ant build 来打包。

4. 通过adb push命令把上一步打包出来的jar文件复制到测试手机中。

adb push <path>/bin/<name>.jar /data/local/tmp/

类似如下代码:

adb push ~/dev/workspace/LaunchSettings/bin/LaunchSettings.jar /data/local/tmp/

运行uiautomator 测试
下面是运行 LaunchSettings.jar jar包中测试代码的命令。测试代码位于com.uia.example.my包中。

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

关于uiautomator 的更多信息参考这里:http://developer.android.com/tools/help/uiautomator/index.html

最佳实践

下面是一些使用uiautomator 做UI测试的最佳实践

  • 在待测应用可能运行的尽可能多的设备上跑uiautomator 测试。例如 在不同的屏幕密度、不同的屏幕尺寸上运行测试。
  • 还应该在一些常规场景下测试UI,例如 电话打入情况、网络连接断开的情况等。
0 0