三、MonkeyRunner复杂的功能开始学习
(1)获取APK文件中ID的两种方式
Monkeyrunner的环境已经搭建完成,现在对Monkeyrunner做一个简介。
Monkeyrunner工具提供了一套API让用户/测试人员来调用,调用这些api可以控制一个Android设备或模拟器,而不需要了解对应的源码。
有了Monkeyrunner,我们可以编写python脚本来控制apk包的安装和卸载、启动app、向app发送各种动作事件、截取图片并保存。
除此之外,MonkeyRunner是Google提供的一个基于坐标点的Android黑盒自动化测试工具。所以,要使用Monkeyrunner进行自动化测试,首先,要了解Monkeyrunner中获取坐标点的方式。

本文中,我们主要介绍两种获取坐标点的方式。一种是通过MonkeyRecorder获取坐标;另一种是通过HierarchyViewer工具获取控件ID。

一、控件坐标获取
1.Pointer location获取坐标
先说一个比较简单的获取坐标的方式,是通过模拟器中的设置-开发者选项,找到“指针位置”的选项,勾选上。如下图所示。

勾选后,模拟器的最顶部则显示坐标,比如点击模拟器上的任一应用,最顶部显示X、Y的值即该应用的坐标;同理,如果想要获取任一应用中的任一位置的坐标,也可用此方法。

MonkeyRecorder获取坐标
下面就MonkeyRecorder获取坐标的方式,进行演示。MonkeyRecorder是一个比较好用的获取坐标的工具,它是用来获取真机或模拟器上坐标的工具,当我们点击真机或模拟器上的空间时,就能显示真机或模拟器上的点击点的坐标。
(1)MonkeyRecorder的启动
首先安卓手机连接上电脑,并保证以下两个条件成立:
a.终端USB调成开发者模式
b.电脑安装手机驱动
手机连接成功后,打开cmd窗口,输入adb devices查看已连接真机或模拟器设备的名称,我们这里仍以模拟器为代表。
之后,在cmd窗口,输入monkeyrunner后,启动Monkeyrunner。做以下操作:导入MonkeyRecorder包、连接模拟器设备、以MonkeyRecorder方式启动模拟器,并依次输入
如下命令:

  • 1   from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice
  • 2
  • 3   from com.android.monkeyrunner.recorder import MonkeyRecorder as recorder
  • 4
  • 5  device=MonkeyRunner.waitForConnection()
  • 6
  • 7  recorder.start(device)

到此,MonkeyRecorder正式启动。截图如下。

2)MonkeyRecorder的使用
我们这里只是使用MonkeyRecorder来记录坐标,获取坐标的方式很简单。比如qq的登录界面,点击“登录”按钮,右侧就会显示该按钮的坐标;同样,点击账号输入框或密码输入框,右侧同样会显示坐标。这个坐标就是我们需要获得的坐标。

同时,MonkeyRecorder中的界面是同模拟器页面保持一致的,在MonkeyRecorder中触发任一操作,模拟器上会有相应的触发。如果两者没有保持一致,则点击MonkeyRecorder右上角的Refresh Display即可刷新页面。

3.控件坐标之Monkeyrunner脚本演示
我们将下面一段Monkeyrunner脚本写到一个test.py文件中,然后运行test.py文件,查看模拟器或真机上是不是做相应的操作。

  • 1      from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice
  • 2
  • 3     device.startActivity(component="com.tencent.mobileqq/.activity.SplashActivity")
  • 4
  • 5     #启动activity(这里启动qq)
  • 6
  • 7     device.startActivity(component="com.tencent.mobileqq/.activity.SplashActivity")
  • 8
  • 9     #登录界面,点击账号输入框
  • 10
  • 11    device.touch(60,300,'DOWN_AND_UP')
  • 12
  • 13   #输入qq账号
  • 14
  • 15   device.type('3469191693')

二、控件ID获取
通过控件ID实现自动化脚本的运行,就性能而言,会比控件坐标的实现差一些;但是对于不同分辨率的设备都通用,不需要动态变换坐标。控件ID的获取主要是通过HierarchyViewer。下面就HierarchyViewer从打开方式和使用两方面进行讲解。
1.HierarchyViewer的打开方式
HierarchyViewer的打开方式有两种:一种是eclipse中打开HierarchyView视图,另外一种是命令行中执行sdk/tools/hierarchyviewer.bat。
HierarchyViewer默认只能在非加密设备使用,例如工程机,工程平板或者模拟器。如果要在手机上使用HierarchyViewer,你需要在你的应用中添加一个开源库View Server。链接地址:https://github.com/romainguy/ViewServer。该篇文章中有讲解如何启动真机View Server,大家如果有兴趣,可参考:https://dup2.org/node/1538。
方式一:连接您的真机设备,或打开模拟器,在eclipse中, 依次选择Window-Open Perspective-Other,在Other中,选择HierarchyView视图,即可打开。

方式二:连接您的真机设备或打开模拟器,运行cmd窗口,进入到sdk/tools目录下,输入命令hierarchyviewer.bat,运行hierarchyviewer。

或者直接在sdk/tools目录下,找到hierarchyviewer.bat,双击运行。

下面讲解利用HierarchyViewer获取控件ID的方法。
2.HierarchyViewer获取控件ID
HierarchyViewer启动后,首先会看到的第一个窗口显示了设备和模拟器的列表。点击左边的箭头,就会展开当前设备或模拟器的Activity对象列表。列表中显示了设备或模拟器上,UI当前可视的所有Activity对象。这些对象按照它们的Android组件名称列出来。列表中的内容包含应用的Activity对象和系统的Activity对象。
当模拟器activity画面变更后,点击refresh可以加载新的页面布局信息。

从列表中选择你的activity名称,双击,或点击菜单栏的Load View Hierarchy按钮,进入View Hierarchy窗口,查看它的view层次结构;或者点击Inspect Screenshot按钮,进入Pixel Perfect窗口,从而查看UI的一个放大图像。我们这里点击进入View Hierarchy窗口。
可以从下图中看到模拟器此activity的画面布局信息,左边部分是hierarchy通过树形结构展示的布局形式,右下角是模拟器上当前页面的UI布局信息。

通过滚动鼠标,可以放大每个树节点;拖拽鼠标,移动树形结构布局。双击树节点可以展示单独的UI部分。从下图中,可以看到,id/btn_login即为登录按钮的ID。依次类推,可以查看其它控件ID。
注:对于列表、或者弹出框则无法直接通过点击ID操作成功,需要计算ID的坐标

(2)Monkeyrunner之控件ID不存在或重复
我们在用monkeyrunner进行Android自动化时,通过获取坐标点或控件ID进行一系列操作。由于使用坐标点时,屏幕分辨率一旦更改,则代码中用到坐标的地方都要修改,这样导致代码的复用率较低。因此,我们多采用控件ID操作(注:控件ID需要在模拟器中使用,对于绝大多数真机不适用)。
但是,某些控件的ID是不存在的或重复存在,那么,遇到这种情况,我们怎样继续使用控件ID进行自动化测呢?
例如,下图中,我想要获取最右侧红框中的id/tv,但是,大家会发现,和它并列的也有重复的控件id值。现在我们就讲述一下这种情况(控件ID不存在同样处理)。

我们从这个控件树的节点角度来思考如何获得控件的引用。我们可以看到在上图hierarchy viewer中的每个控件所对应的框形中,右下角都有一个数字。其实这个数字就是该控件在同级兄弟节点中的索引值,我们知道这个索引值后,就可以根据parentView.children[index]属性来获取任意父节点所对应的子节点的对象引用。其中的parentView可以是树形图中有效ID的任意父节点(父节点要保证唯一有效),然后利用python函数的可变参数列表特性来传入所需控件的索引列表即可构造出得到任意节点引用的字符串,从而得到其引用。
核心代码如下,把如下代码加入自己的python脚本中,直接调用该函数即可。

for index in childSeq:
childView += ('.children[' + str(index) + ']')
print childView
return eval(childView)

#获取id的文本
def getText(view):
if view != None:
return (view.namedProperties.get('text:mText').value)

  • 1   #定义获取重复或不存在控件id,寻找子节点函数
  • 2   def getChildView(parentId, *childSeq):
  • 3   hierarchyViewer = device.getHierarchyViewer()
  • 4   childView="hierarchyViewer.findViewById('" + parentId +"')"
  • 5   for index in childSeq:
  • 6   childView += ('.children[' + str(index) + ']')
  • 7   print childView
  • 8   return eval(childView)
  • 9
  • 10   #获取id的文本
  • 11   def getText(view):
  • 12   if view != None:
  • 13   return (view.namedProperties.get('text:mText').value)

有了以上代码之后,我们可以获取上图中的id/tv,方法如下:
getChildView(‘id/province_list’,5,0,0)
其中结合上图可知,getChildView的第一个参数即:有效且唯一的父节点
参数二、三依次为要获取的控件ID的父节点的父节点
注:用到的父节点即图中的id/province_list,有效且唯一的值。当前的父节点右下角的角标,不需要在getChildView函数中显示。
这样,通过以上函数,再结合Hierarchyviewer图形,我们获取到了重复的控件ID。
由于Hierarchyviewer看起来不是特别方便,这里再推荐一款和Hierarchyviewer类似功能的工具:uiautomatorviewer(存储在sdk\tools中,双击打开即可)

由上图中,uiautomatorviewer每个控件前面的数字即相当于Hierarchyviewer的角标,我们同样可以获取到目标ID的最终有效且唯一的父节点,从而调用函数getChildView(‘id/province_list’,5,0,0)
获取到了不存在或重复的控件ID后,我们可以通过其坐标,进行点击操作。
首先,定义一个“获取指定按钮坐标”的函数

  • 1   def  getBtnPoint(btn):
  • 2         print btn
  • 3         point = device.getHierarchyViewer().getAbsoluteCenterOfView(btn);
  • 4         return point

然后通过坐标,实现点击操作,例如:

askView = getChildView('id/tabs',1)
askPpoint = getBtnPoint(askView)
device.touch(askPpoint.x,askPpoint.y,'DOWN_AND_UP')

  • 1  askView = getChildView('id/tabs',1)
  • 2  askPpoint = getBtnPoint(askView)
  • 3  device.touch(askPpoint.x,askPpoint.y,'DOWN_AND_UP')

到这里,我们介绍完了处理控件ID不存在或重复时的方法,自己实践一把,就会更能体会

Hierarchyviewer/uiautomatorviewer+getChildView()获取不存在或重复控件ID的用法。

(3)录制脚本与回放脚本

录制操作:
在cmd下输入monkeyrunner recorder.py,将打开下面的窗口,该窗口的功能:
1、可以自动显示手机当前的界面
2、自动刷新手机的最新状态
3、点击手机界面即可对手机进行操作,同时会反应到真机,而且会在右侧插入操作脚本
4:、wait: 用来插入下一次操作的时间间隔,点击后即可设置时间,单位是秒
Press a Button:用来确定需要点击的按钮,包括menu、home、search,以及对按钮的press、down、up属性
Type Something:用来输入内容到输入框
Fling:用来进行拖动操作,可以向上、下、左、右,以及操作的范围
Export Actions:用来导出脚本
Refresh Display:用来刷新手机界面,估计只有在断开手机后,重新连接时才会用到

5.在左侧手机视图上做的任何操作,在右侧都会进行脚本录制
上述实例录制的操作脚本如下:
TOUCH|{‘x’:187,’y’:356,’type’:’downAndUp’,}
PRESS|{‘name’:’MENU’,’type’:’downAndUp’,
WAIT|{‘seconds’:5.0,}
DRAG|{‘start’:(192,128),’end’:(192,640),’duration’:1.0,’steps’:10,}

回放操作:
回放:使用命令monkeyrunner recorder_playback.py record_test.py,其中record_test.py中是我们录制的脚本,这里需要使用绝对路径,即回放脚本和录制操作脚本都必须在Monkeyrunner.bat所在目录。
PS: 录制后的脚本可以进行二次更改,而且每一步操作需要有时间间隔,以保证测试的正确性

(4)MonkeyRunner常用事件

这里给大家罗列下Monkeyrunner的常用事件,基本上这些事件都能够满足我们日常写用例的需求了。

#monkeyrunner导入模块

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage

#monkeyrunner连接设备

device = MonkeyRunner.waitForConnection()
if not device:
print "Please connect a device to start!"
else:
print "Start "
#monkeyrunner启动一个Activity

componentName="com.ss.android.article.news/.activity.SplashActivity"

device.startActivity(component=componentName)

#monkeyrunner按键

发送指定键的关键事件:  device.press(参数1:键码, 参数2:触摸事件类型)

参数1:常用键内容

  按下HOME键 device.press('KEYCODE_HOME', MonkeyDevice.DOWN_AND_UP)

  按下BACK键 device.press('KEYCODE_BACK', MonkeyDevice.DOWN_AND_UP)

  按下下导航键 device.press('KEYCODE_DPAD_DOWN', MonkeyDevice.DOWN_AND_UP)

  按下上导航键 device.press('KEYCODE_DPAD_UP', MonkeyDevice.DOWN_AND_UP)

  按下OK键 device.press('KEYCODE_DPAD_CENTER', MonkeyDevice.DOWN_AND_UP)

  按下左导航键 device.press('KEYCODE_DPAD_LEFT', MonkeyDevice.DOWN_AND_UP)

  按下右导航键 device.press('KEYCODE_DPAD_RIGHT', MonkeyDevice.DOWN_AND_UP)

  相应的按键对应名称:

  menu键:KEYCODE_MENU

  home键:KEYCODE_HOME

  back键:KEYCODE_BACK

  search键:KEYCODE_SEARCH

  call键:KEYCODE_CALL

  end键:KEYCODE_ENDCALL

  上音量键:KEYCODE_VOLUME_UP

  下音量键:KEYCODE_VOLUME_DOWN

  power键:KEYCODE_POWER

  camera键:KEYCODE_CAMERA

#monkeyrunner卸载包

device.removePackage ('com.example.android.notepad')

print ('卸载成功')

#monkeyrunner安装包

device.installPackage('ApiDemos.apk')
print ('安装成功')

#monkeyrunner单击控件

方式1:device.touch(507,72,"DOWN_AND_UP")

方式2:easy_device.touch(By.id('id/qingchu'),device.DOWN_AND_UP)

用后者需要导入

from com.android.chimpchat.hierarchyviewer import HierarchyViewer #根据ID找到ViewNode,对viewnode的一些操作等

from com.android.monkeyrunner.easy import EasyMonkeyDevice #提供了根据ID进行访问方法touch、drag等

from com.android.monkeyrunner.easy import By #根据ID返回PyObject的方法

from com.android.hierarchyviewerlib.models import ViewNode as vn #代表一个控件,可获取控件属性

#monkeyrunner长按控件

方式1:device.touch(507,72,"DOWN_AND_UP")

device.touch(507,72,MonkeyDevice.DOWN)

MonkeyRunner.sleep(1)
device.touch(507,72,MonkeyDevice.UP)
方式2:
easy_device.touch(By.id('id/qingchu'),,MonkeyDevice.DOWN)
MonkeyRunner.sleep(1)
easy_device.touch(By.id('id/qingchu'),MonkeyDevice.UP)

用后者需要导入

from com.android.chimpchat.hierarchyviewer import HierarchyViewer #根据ID找到ViewNode,对viewnode的一些操作等

from com.android.monkeyrunner.easy import EasyMonkeyDevice #提供了根据ID进行访问方法touch、drag等

from com.android.monkeyrunner.easy import By #根据ID返回PyObject的方法

from com.android.hierarchyviewerlib.models import ViewNode as vn #代表一个控件,可获取控件属性

#monkeyrunner滑动屏幕

for i in range(1,70):

device.drag((250,110),(250,850),0.1,10)

MonkeyRunner.sleep(1)

#monkeyrunner延时

MonkeyRunner.sleep(3)

#monkeyrunner截图

result = device.takeSnapshot()

result.writeToFile('C:\\Users\\Martin\\Desktop\\test.png','png')

#monkeyrunner截图对比

result1.sameAs(result0,1.0)

#monkeyrunner局部图片(前两个值是左上角左边,后两个值是右下角减左上角的坐标。)

pic0= result0.getSubImage((4,41,400,700))

#monkeyrunner重启设备

device.reboot()

#monkeyrunner单击电源键,熄灭屏幕

device.press('KEYCODE_POWER',MonkeyDevice.DOWN_AND_UP)

#monkeyrunner唤醒屏幕

device.wake()

#monkeyrunner输入文本

Cotent='1234'

device.type(Cotent)

最全的MonkeyRunner自动化测试从入门到精通(10)的更多相关文章

  1. 史上最全的MonkeyRunner自动化测试从入门到精通(3)

    原文地址https://blog.csdn.net/liu_jing_hui/article/details/60956088 MonkeyRunner复杂的功能开始学习 (1)获取APK文件中ID的 ...

  2. 最全的MonkeyRunner自动化测试从入门到精通(9)

    最基本脚本功能开始编写(1)Monkeyrunner和Monkey的区别 1)Monkeyrunner工具在工作站上通过API定义的特定命令和事件控制设备或模拟器(可控) 2)精确控制事件之间的事件 ...

  3. 最全的MonkeyRunner自动化测试从入门到精通(8)

    在eclipse中的一些剩余配置操作步骤一:pyhon的在eclipse配置,如图所示: 步骤二:jython的在eclipse中的配置, 在window-preference-PyDev-Jytho ...

  4. 最全的MonkeyRunner自动化测试从入门到精通(6)

    eclipse中进行插入PyDev插件的使用步骤一:monkeyrunner环境变量的配置.在Android Sdk中的tools目录下,拷贝路径,进行配置环境变量.与上面的配置方法一样,在这里不做过 ...

  5. 最全的MonkeyRunner自动化测试从入门到精通(5)

    夜神模拟器的安装与配置步骤一:我们为什么会选择使用夜神模拟器呢? 众所周知,Android studio的模拟器运行速度也很快,可以媲美真机.虽然其运行速度很快,可以满足我们测试的需求.但仍存在以下问 ...

  6. 史上最全的MonkeyRunner自动化测试从入门到精通(2)

    原文地址https://blog.csdn.net/liu_jing_hui/article/details/60955696 最基本脚本功能开始编写 (1)Monkeyrunner和Monkey的区 ...

  7. 史上最全的MonkeyRunner自动化测试从入门到精通(1)

    原文地址https://zhuanlan.zhihu.com/p/26043620 MonkeyRunner使用 #-*- coding:utf-8 –*- from com.android.monk ...

  8. 最全的MonkeyRunner自动化测试从入门到精通(7)

    jython-installer-2.5.3.jar安装步骤步骤一:Jython的安装比较简单,Jython的安装程序本身就是一个Java应用程序,因此,在安装之前,你必须具备Java运行的环境. 步 ...

  9. 最全的MonkeyRunner自动化测试从入门到精通(4)

    Android Sdk环境变量配置步骤一:我们进行再eclipse中下载sdk来进行使用. 在安装ADT插件完成之后,在eclipse的菜单界面会多一个ADT的管理器,如下图,点击进入到安卓API安装 ...

随机推荐

  1. 20款时尚的 WordPress 简洁主题【免费下载】

    在这篇文章中,我们收集了20款时尚的 WordPress 简洁模板.WordPress 是最流行的博客系统,插件众多,易于扩充功能.安装和使用都非常方便,而且有许多第三方开发的免费模板,安装方式简单易 ...

  2. Demo学习: Basic jQuery

    UniGUI是一套基于ExtJS的Delphi的WEB框架,它是使用ExtPascal来转化到ExtJS,ExtJS是一个跨浏览器的JavaScript库,因此UniGUI发布出来的程序可以在各种浏览 ...

  3. Umbraco Forms 使Rendering Forms scripts 在不同的template中

    具体请参考 https://our.umbraco.org/documentation/products/umbracoforms/developer/Rendering-Scripts/ 转载 ht ...

  4. Table嵌套去掉子table的外边框

    Table表格去掉子表格的边框 1. 父表格 <table align="center" style="border:none;cell-padding:0; ce ...

  5. JS--dom对象:document object model文档对象模型

    dom对象:document object model文档对象模型 文档:超文本标记文档 html xml 对象:提供了属性和方法 模型:使用属性和方法操作超文本标记性文档 可以使用js里面的DOM提 ...

  6. android如何查看cpu的占用率和内存泄漏

    在分析内存优化的过程中,其中一个最重要的是我们如何查看cpu的占用率和内存的占用率呢,这在一定程度上很重要,经过查询资料,研究了一下,暂时了解到大概有以下几种方式,如果哪位高手有更好的办法,或者文中描 ...

  7. inaccessible

    $w = (object)array('key0'=>'a','key1'=>'b',0,1,2,0=>'0w',1=>'1w','11'=>'11str'); var_ ...

  8. PHP学习心得2

    对于PHP的语法结构,刚开始真的很不习惯,真搞不懂为什么每个变量之前都要加个“$”符号,每个语句写完之后都必须加上“分号”来表示此句已经结束,还有,PHP对字母的大小写是敏感的,写的时候一定要注意大小 ...

  9. charCodeAt方法以及Unicode中文汉字编码范围

    js的charCodeAt() 方法可返回指定位置的字符的 Unicode 编码.这个返回值是 0 - 65535 之间的整数. 在字符串 "Hello world!" 中,我们将 ...

  10. LVS原理详解以及部署

    linux virtual server简称LVS,Internet的快速增长使多媒体网络服务器面对的访问数量快速增加,服务器需要具备提供大量并发访问服务的能力,因此对于大负载的服务器来讲, CPU. ...