Android UIAutomator2.0入门

Android UIAutomator2.0入门

Uiautomator是由谷歌推出的用于UI自动化测试的工具,花了一天时间研究了下,总体来说还是非常简单,api非常简洁,今天主要帮助大家入门。对于安卓环境搭建我就不多讲了,我们直接进入Uiautomator讲解。

1 创建工程

直接用android studio创建一个空工程。启动studio,点击start a new Android Studio project,在application name处填上工程名,点击 Next, 在target android devices页面,选择默认最小的sdk,点next,在点add no activity,点finish,这样就创建好了一个新工程。

2 添加配置

在Module:app里的build.gradle的dependencies方法中,添加

implementation'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'。复制代码

最后点击refresh all gradle按钮,更新uiautomator。

3 基础api

主要用到的两个对象device(直接操作设备),UiObject2(ui节点对象)。所有的ui测试都是基于设备或者节点对象,进行相关操作。只要吃透了这些方法的用法,写代码就可以信手拈来。

1.UiDevice使用

UiDevice按键

返回值方法名说明

booleanpressBack()模拟短按返回back键

booleanpressDPadCenter()模拟按轨迹球中点按键

booleanpressSPadDown()模拟轨迹球向下按键

booleanpressDPadLeft()模拟轨迹球向左按键

booleanpressDPadRight()模拟轨迹球向右按键

booleanpressDPadUp()模拟轨迹球向上按键

booleanpressDelete()模拟短按删除delete按键

booleanpressEnter()模拟短按回车enter键

booleanpressHome()模拟短按home键

booleanpressKeyCode(int keyCode,int metaState)模拟短按键盘代码keycode

booleanpressKetCode(int keyCode)模拟短按键盘代码keycode

booleanpressMenu()模拟短按menu键

booleanpressRecentApps()模拟短按最近使用程序

booleanpressSearch()模拟短按搜索键

主要用到的按键方法

UiDevice.getInstance().pressBack();//点击返回键UiDevice.getInstance().pressHome();//点击Home键UiDevice.pressKeyCode(KeyEvent.KEYCODE);//键盘按键复制代码

手势操作

click() 点击dragTo() 拖动当前元素swipe() 向上下左右滑动复制代码

其它高级用法暂时不做讨论,需要用到的话直接调用即可,例如唤醒屏幕,截屏等

2.UiObject2使用

基础动作模拟API

返回API说明

voidclear()清除编辑框中的内容

voidclick()点击一个对象

<R> RclickAndWait(EventCondition<R> condition, long timeout)点击一个对象,然后等待在超时时间内条件成立则通过,否则抛出异常

voiddrag(Point dest, int speed)自定义速度拖拽一个对象到指定位置,速度:像素/秒

voiddrag(Point dest)拖拽一个对象到指定位置

voidlongClick()长时间点击对象

booleanscroll(Direction direction, float percent)滚动操作

booleanscroll(Direction direction, float percent, int speed)自定义速度的滚动操作

voidsetText(String text)设置文本内容

手势API

返回API说明

voidpinchClose(float percent, int speed)自定义速度关闭手势

voidpinchOpen(float percent, int speed)自定义速度打开手势

voidpinchOpen(float percent)打开手势

booleanfling(Direction direction)滑动手势

booleanfling(Direction direction, int speed)自定义速度滑动手势

voidswipe(Direction direction, float percent, int speed)自定义速度滑动手势

voidswipe(Direction direction, float percent)自滑动手势

组件属性API

返回API说明

StringgetApplicationPackage()返回应用包名

StringgetClassName()返回对象类名

StringgetContentDescription()返回内容描述

StringgetResourceName()返回资源id

StringgetText()返回文本

RectgetVisibleBounds()返回对象可见范围内的屏幕坐标

PointgetVisibleCenter()返回可见范围的中心

booleanisCheckable()返回Checkable属性

booleanisChecked()返回Checked属性

booleanisClickable()返回Clickable属性

booleanisEnabled()返回Enabled属性

booleanisFocusable()返回Focusable属性

booleanisFocused()返回isFocused属性

booleanisLongClickable()返回LongClickable属性

booleanisScrollable()返回Scrollable属性

booleanisSelected()返回Selected属性

层级关系API

返回API说明

UiObject2findObject(BySelector selector)在该对象层级之下,返回第一个与条件匹配的对象

List<UiObject2>findObjects(BySelector selector)在该对象层级之下,返回所有匹配的对象

List<UiObject2>getChildren()返回该对象的所有子元素的集合

UiObject2getParent()返回该对象的父元素

intgetChildCount()返回该对象的直接子元素的数量

条件判断API

返回API说明

booleanequals(Object object)比较两个对象是否相等

inthashCode()获取对象的hashCode

booleanhasObject(BySelector selector)返回对象是否存在

<R> Rwait(UiObject2Condition<R> condition, long timeout)等待的条件得到满足

<R> Rwait(SearchCondition<R> condition, long timeout)等待的条件得到满足

注意:进行手势操作的时候,最好需要进行Thread.sleep()延迟操作,执行动画以及更新ui操作都是需要时间的,如果执行下个方法查找节点时页面还未及时更新,则会出现获取对象失败导致直接跑出异常。此时需要用到hasObject()判断对象是否存在,可以处理多种状态的逻辑判断,例如登录和未登陆显示的ui不一样,则需要根据节点判断当前是否处于登录状态。

4 在androidTest目录下写代码

接下来我们就简单的写个case来熟悉下基本操作,就做个简单的打开微信(已登录状态下,未登陆的情况大家熟练后在自行编写),然后发送聊天对话。

package com.appiumtest;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.support.test.InstrumentationRegistry;import android.support.test.runner.AndroidJUnit4;import android.support.test.uiautomator.By;import android.support.test.uiautomator.Direction;import android.support.test.uiautomator.UiDevice;import android.support.test.uiautomator.UiObject2;import android.support.test.uiautomator.Until;import android.util.Log;import org.junit.Test;import org.junit.runner.RunWith;/** * Instrumentedtest,whichwill execute on an Android device. * * author tangge by 2018-04-16 * * @see Testing documentation */@RunWith(AndroidJUnit4.class)public class ExampleInstrumentedTest2 {    private UiDevice device = null;    private String packageName ="com.tencent.mm";    @Test    public voidstartUp(){        Context appContext = InstrumentationRegistry.getTargetContext();        try {            useAppContext(appContext);        } catch (Exception e) {            e.printStackTrace();            Log.e("UiDevice",e.getMessage());        }    }    private void useAppContext(Context context) throws Exception {        // Context of the app under test.        device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());        device.pressHome();        startApp(context);        //已登录状态,点击列表中第一个对话        sleep(10);        swipe("b2m",Direction.LEFT);//左滑        swipe("b2m",Direction.RIGHT);//右滑        clickListView("c3p",0,1);//点击第一个对话        click("aaf");//点击输入框        getObjById("aaf",1).setText("你好");        click("aal",1);//发送        click("h9",1);//点击返回    }    //启动APP    private void startApp(Context context){        Intent intent = new Intent();        intent.setComponent(new ComponentName(packageName, packageName+".ui.LauncherUI"));        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);        context.startActivity(intent);    }    private UiObject2 getObjById(String id,floatsencend){returndevice.wait(Until.findObject(By.res(packageName, id)), sencend > 0 ? (long) (sencend * 1000) : 200);    }    //点击    private void click(String id) throws Exception{        click(id,0);    }    //延迟点击    private void click(String id,floatsencend) throws Exception{if(exitObj(id,sencend)){            getObjById(id,0).click();        }    }    //延迟点击    private voidsetText(String id, String text ,floatsencend) throws Exception{if(exitObj(id,sencend)){            getObjById(id,0).setText(text);        }    }    //判断是否存在该对象    private booleanexitObj(String id,floatsencend) throws Exception{        sleep(sencend);returndevice.hasObject(By.res(packageName,id));    }    //判断是否存在该对象    private booleanexitObjByText(String text,floatsencend) throws Exception{        sleep(sencend);returndevice.hasObject(By.text(text));    }    //延迟2秒滑动    private void swipe(String id, Direction direction) {        getObjById(id,3).swipe(direction,0.8f,4000);    }    //点击列表第几个元素    private void clickListView(String id,int position,floatsencend) {        //点击第几个        getObjById(id,sencend).getChildren().get(position).click();    }    private void sleep(floatsencend) throws Exception{        Thread.sleep(sencend > 0 ? (long) (sencend * 1000) : 500);    }}复制代码

右击测试文件,点击运行即可。代码中已经封装了点击,滑动,判断对象是否存在,点击list列表等方法。希望大家能通过这个简单case快速入门,然后编写出完整的一套测试流程。源码附上download.csdn.net/download/qq…

原创地址 https://juejin.im/post/5ad6e89451882555653507c8

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,345评论 0 17
  • 先说一下这篇文章里面的内容:TCP 客户端, 自定义对话框, 自定义按钮, ProgressBar竖直显示, 重力...
    杨奉武阅读 3,262评论 0 3
  • ​ 如何写出优等级的本科毕业论文? 我有特殊的写论文技巧。 在忙碌的大四,我并没有因为论文的缘故而放弃实习,同时我...
    墨霜阅读 8,966评论 32 326
  • 姓名:刘小琼 公司:宁波大发化纤有限公司 宁波盛和塾《六项精进》第235期学员 【日精进打卡第65天】 知~学习 ...
    刘小琼123阅读 107评论 0 0
  • 水木然的《个体崛起》,他送我的,确实解答了我心中很大的疑问。 过去旧有的,也许姑且说成小灰人和爬虫类人等进化程度的...
    善见润阅读 172评论 0 3