欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自动化测试 uiautomator 入门

程序员文章站 2022-07-12 18:39:39
...

选择原因

  1. API接口丰富,包括 android 所有事件。不依赖屏幕坐标控制。
  2. 对比Rubotium,无需新建测试项目。无需为了测试多安装个apk,而且不必进入 adb shell 环境调起测试程序。

简单例子

亮屏进入测试app界面点击按钮的简单操作

public class MatorTest extends UiAutomatorTestCase{

    public void test() throws RemoteException, UiObjectNotFoundException {
        System.out.println("\n \n  -- MyLogInfo start --\n \n");

        UiDevice uiDevice = getUiDevice();

        System.out.println(" 亮屏,上滑解锁,左滑进入第二屏 ");
        uiDevice.wakeUp();
        sleep(500);
        uiDevice.swipe(uiDevice.getDisplayWidth() / 2, uiDevice.getDisplayHeight() - 20, uiDevice.getDisplayWidth() / 2, uiDevice.getDisplayHeight() / 2, 5);
        sleep(500);
        uiDevice.pressHome();
        sleep(1000);
        uiDevice.swipe(uiDevice.getDisplayWidth() - 20, 100, uiDevice.getDisplayWidth() / 2, 100, 10);
        sleep(500);


        System.out.println(" 进入AutomatorTest ");
        UiObject myAppButton = new UiObject(new UiSelector().text("AutomatorTest"));
        myAppButton.clickAndWaitForNewWindow();


        System.out.println(" 进入软件后的操作 ");
        UiObject btn1 = new UiObject(new UiSelector().className(Button.class).text("button1"));
        btn1.click();

        UiObject btn2 = new UiObject(new UiSelector().className(Button.class).text("button2"));
        btn2.click();

        UiObject btn3 = new UiObject(new UiSelector().className(Button.class).text("button3"));
        btn3.click();

        UiObject btnJump = new UiObject(new UiSelector().className(Button.class).text("跳转"));
        btnJump.click();
        sleep(300);


        System.out.println(" 系统按键操作 ");
        uiDevice.pressBack();
        sleep(300);
        uiDevice.pressHome();
        sleep(300);

        System.out.println("\n \n  -- MyLogInfo end -- \n \n");
    }
}

uiautomatorviewer

启动

位于 sdk\tools\uiautomatorviewer.bat。命令行打开进入界面
自动化测试 uiautomator 入门

操作

分别对应左上角的四个按钮,从左到右的顺序

  1. 打开
  2. Device ScreenShot( uiautomator dump)
    一般层次截图,将所有的层次展示
  3. Device ScreenShot with Compressed Hierarchy(uiautomator dump –compressed)
    压缩层次截图。多个层次压缩为一层展示
  4. 保存
    当当前分析的结果保存,两个文件:png、uix

批处理脚本。再也不用手动编译、执行测试脚本

自动完成测试脚本所有过程(构建、编译、Push、运行)如下:

  1. cd/d d:\es\sdk\tools\
  2. android create uitest-project -n test -t 9 -p D:\AndroidWorkspace\AutomatorTest
  3. cd/d d:\AndroidWorkspace\AutomatorTest
  4. ant build
  5. adb push D:\AndroidWorkspace\AutomatorTest\bin\test.jar data/local/tmp
  6. adb shell uiautomator runtest test.jar -c com.example.automatortest.test.MatorTest

【1、2】 利用 android.bat 生成脚本配置文件:build.xml。位于工程的主目录下

【3、4】 ANT 工具将 build.xml 配置转换为 jar 测试脚本

【5】 将 jar 测试脚本推送到手机目录的 data/local/tmp

【6】 使用 uiautomator 工具运行手机目录中存在的 test.jar 文件去去测试指定工程

若每次使用都需要手动输入编译语句,不同的文件夹切换。会很不方便,白白浪费时间。变写了自动编译脚本。不同的工程变化下目录文件就可以了。

windows -> .bat(.cmd)

cmd /k "cd/d d:\es\sdk\tools\ && android create uitest-project -n test -t 9 -p D:\AndroidWorkspace\AutomatorTest && cd/d d:\AndroidWorkspace\AutomatorTest && ant build && adb push D:\AndroidWorkspace\AutomatorTest\bin\test.jar data/local/tmp && adb shell uiautomator runtest test.jar -c com.example.automatortest.test.MatorTest"

将上述代码复制到txt文本中将后缀名改为.bat(.cmd),双击运行即可。需要手动修改各个部分路径指向。

附录

UiAutomator 接口

对象:UiDevice

对设备进行的操作

坐标参数

  • boolean click(int x, int y)
    • 在坐标点(x, y)点击
  • int getDisplayHeight()
    • 获取屏幕高度
  • int getDisplayWidth()
    • 获取屏幕宽度
  • Point getDisplaySizeDp()
    • 获取显示尺寸大小

系统信息

  • void getCurrentPackageName()
    • 获取当前界面包名
  • void getCurrentActivityName()
    • 获取当前界面Activity
  • void dumpWindowHierarchy(fileName)
    • dump当前布局文件到/data/local/tmp/目录

滑动、拖拽

  • boolean drag(startX, startY, endX, endY, steps)
    • 拖拽坐标处对象到另一个坐标
  • boolean swipe(segments, segmentSteps)
    • 在Points[]中以segmentSteps滑动
  • boolean swipe(startX, startY, endX, endY, steps)
    • 通过坐标滑动

系统按键

- void wakeUp()
    - 按电源键亮屏
- void sleep()  
    - 按电源键灭屏
- boolean isScreenOn()
    - 亮屏状态
- void setOrientationLeft()
    - 禁用传感器,并左旋屏幕,固定
- void setOrientationNatural()
    - 禁用传感器,恢复默认屏幕方向,固定
- void setOrientationRight()
    - 禁用传感器,并右旋屏幕,固定
- void unfreezeRotation()
    - 启用传感器,并允许旋转
- boolean isNaturalOrientation()
    - 检测是否处于默认旋转状态
- void getDisplayRotation()
    - 返回当前旋转状态,01、、23分别代表090180270度旋转
- void freezeRotation()
    - 禁用传感器,并冻结当前状态
- boolean takeScreenshot(storePath)
    - 当前窗口截图、1.0f缩放、90%质量保存在storePath
- void takeScreenshot(storePath, scale, quality)
    - 同上,但指定缩放和压缩比率
- void openNotification()
    - 打开通知栏
- void openQuickSettings()
    - 打开快速设置

等待窗口

- void waitForIdle()
    - 等待当前窗口处于空闲状态、默认10s
- void waitForIdle(long timeout)
    - 自定义超时等待当前窗口处于空闲状态
- boolean waitForWindowUpdate(packageName, timeout)
    - 等待窗口内容更新

对象:UiSelector

UI控件搜索,通过条件、属性控件。定位若多个符合条件的默认返回第一个UiObject。也可以instance()指定第几个

通过 text、description 属性定位

- UiSelector text(text)
    - 通过text完全定位
- UiSelector textContains(text)
    - 通过text包含定位
- UiSelector textMatches(regex)
    - 通过text正则定位
- UiSelector textStartsWith(text)
    - 通过text起始文字定位
- UiSelector description(text)
    - 通过text完全定位
- UiSelector descriptionContains(text)
    - 通过description包含定位
- UiSelector descriptionMatches(regex)
    - 通过description正则定位
- UiSelector descriptionStartsWith(text)
    - 通过description起始文字定位

通过resourceId定位

- UiSelector resourceId(id)
    - 通过resourceId定位
- UiSelector resourceIdMatches(regex)
    - 通过resourceId正则定位

通过class、package定位

- UiSelector className(className)
    - 通过class定位
- UiSelector classNameMatches(regex)
    - 通过class正则定位
- UiSelector packageName(name)
    - 通过package定位
- UiSelector packageNameMatches(regex)
    - 通过package正则定位

通过index、instance定位

- UiSelector    index(index)
    - 通过index定位
- UiSelector    instance(instance)
    - 通过instance定位

通过其他属性定位

- UiSelector    enabled(val)
    - 通过enabled属性定位

Android 的 View 对象的所有属性都可以使用,这里不再列举。

对象:UIObject

代表一个控件,注意:每次使用 UiObject 对象时,都会在当前屏幕重新查找。
Android 中 View 的常用操作都有,列举重要的几个

状态和属性

- boolean   setText(text)
    - 设置内容为text
-boolean    clearTextField()
    - 清除文本
- boolean   isCheckable()
    - 获取对象checkable状态
- boolean   exists()
    - 对象是否存在
- boolean   waitForExists(timeout)
    - 等待对象出现
- boolean   waitUntilGone(timeout)
    - 等待对象消失
- Rect  getBounds()
    - 获取对象矩形范围
- int   getChildCount()
    - 获取子View数量

手势操作

- boolean click()
    - 点击对象。可以指定位置,如右下角:clickBottomRight() ...
- boolean longClick()
    - 长按对象。可以指定位置,如右下角:longClickBottomRight() ...
- boolean   dragTo(destObj, steps)
    - 以steps拖动对象到destObj
- boolean   dragTo(destX, destY, steps)
    - 以steps拖动对象到坐标
- boolean swipeTop(steps)
    - 向上拖动。也可以是其他方向。swipeRight() ...
- boolean   clickAndWaitForNewWindow()
    - 点击对象并等待新窗口出现。也可以加入延时时间。clickAndWaitForNewWindow(timeout)
- boolean   performMultiPointerGesture(touches)
    - 执行单指手势
- boolean   performTwoPointerGesture(startPoint1, startPoint2, endPoint1, endPoint2, steps)
    - 执行双指手势
- boolean   pinchIn(percent, steps)
    - 双指向内收缩
- boolean   pinchOut(percent, steps)
    - 双指向外张开

对象:UiCollection

代表控件集合,相当于ViewGroup和其子控件,使用UiSelector查找
继承 UiObject 对象,有它所有的方法

- int getChildCount()
    - 获取所有子元素数量
- int getChildCount(childPattern)
    - 获取所有子元素中符合 UiSelector 条件的子元素数量
- UiObject getChild(childPattern)
    - 根据 UiSelector 查找子元素
- UiObject  getChildByDescription(childPattern, text)
    - 默认滚动,根据 UiSelector、description text 条件查找子元素
- UiObject  getChildByInstance(childPattern, instance)
    - 默认滚动,根据 UiSelector、instance 条件查找子元素
- UiObject  getChildByText(childPattern, text)
    - 默认滚动,根据 UiSelector、text 条件查找子元素

对象:UiScrollable

继承了 UiCollection 所有方法,还加上了滚动的处理

滑动

- boolean   setAsHorizontalList()
    - 设置水平滚动,步长为5。垂直滚动:setAsVerticalList()
- boolean   flingForward()
    - 快速向前滑动。向后flingBackward()。
- boolean   flingToBeginning(maxSwipes)
    - 不超过maxSwipes向前滑动。
- boolean   scrollBackward(steps)
    - scroll使用和fling相识。可以指定指定步长。
- boolean   scrollIntoView(selector)
    - 滚动到条件元素所处的位置
- boolean   scrollTextIntoView(text)
    - 滚动到文本对象所处的位置
- boolean   scrollIntoView(obj)
    - 滚动到obj所处的位置

属性获取、设置

- boolean   getMaxSearchSwipes()
    - 获取最大可扫动次数、默认30。设置:setMaxSearchSwipes(swipes)
- double    getSwipeDeadZonePercentage()
    - 获取滑动无效区域(到顶部的百分比)。设置:setSwipeDeadZonePercentage(swipeDeadZonePercentage)
- boolean   getChildByDescription(childPattern, text, allowScrollSearch)
    - 是否允许滚动,查找childPattern UiSelector所对应的text子元素

对象:UiWatcher

Interface,用于处理脚本执行过程中遇到非预想的步骤

- boolean checkForCondition()
    - 条件检查回调