Monkey、MonkeyRunner自动化测试文档

时间:2022-04-17 01:51:08

Monkey测试文档

Monkey介绍:

Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中。它向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试。Monkey测试是一种为了测试软件的稳定性、健壮性的快速有效的方法。

Monkey的特征

1、 测试的对象仅为应用程序包,有一定的局限性。
2、 Monky测试使用的事件流数据流是随机的,不能进行自定义。
3、 可对Test的对象,事件数量,类型,频率等进行设置。

Monkey测试的停止条件

1、如果限定了Monkey运行在一个或几个特定的包上,那么它会监测试图转到其它包的操作,并对其进行阻止。
2、如果应用程序崩溃或接收到任何失控异常,Monkey将停止并报错。
3、如果应用程序产生了应用程序不响应(application not responding)的错误,Monkey将会停止并报错。

Monkey的基本用法

基本语法如下:

Monkey、MonkeyRunner自动化测试文档

Monkey、MonkeyRunner自动化测试文档
详细的monkey介绍,和options的参数请查看 (http://developer.android.com/guide/developing/tools/monkey.html
如果不指定options,Monkey将以无反馈模式启动,并把事件任意发送到安装在目标环境中的全部包。

使用步骤:

1) 进入platform-tools目录下:
Monkey、MonkeyRunner自动化测试文档
2) Android studio连接真机(虚拟机),在Linux系统下打开shell(Window打开CMD),命令行输入:adb shell,进入shell界面:
Monkey、MonkeyRunner自动化测试文档
3) 执行Monkey命令:
Monkey、MonkeyRunner自动化测试文档

其他参数设置(可以省略):

adbshellmonkey[options]optionsMonkey500 adb shell monkey -p your.package.name -v 500
一些常用的参数信息:
-v
命令行的每一个-v将增加反馈信息的级别。Level 0(缺省值)除启动提示、测试完成和最终结果之外,提供较少信息。Level 1提供较为详细的测试信息,如逐个发送到Activity的事件。Level 2提供更加详细的设置信息,如测试中被选中的或未被选中的Activity。
事件
-s
伪随机数生成器的seed值。如果用相同的seed值再次运行Monkey,它将生成相同的事件序列。
–throttle
在事件之间插入固定延迟。通过这个选项可以减缓Monkey的执行速度。如果不指定该选项,Monkey将不会被延迟,事件将尽可能快地被产成。
–pct-touch
调整触摸事件的百分比(触摸事件是一个down-up事件,它发生在屏幕上的某单一位置)。
–pct-motion
调整动作事件的百分比(动作事件由屏幕上某处的一个down事件、一系列的伪随机事件和一个up事件组成)。
–pct-trackball
调整轨迹事件的百分比(轨迹事件由一个或几个随机的移动组成,有时还伴随有点击)。
–pct-nav
调整“基本”导航事件的百分比(导航事件由来自方向输入设备的up/down/left/right组成)。
–pct-majornav
调整“主要”导航事件的百分比(这些导航事件通常引发图形界面中的动作,如:5-way键盘的中间按键、回退按键、菜单按键)
–pct-syskeys
调整“系统”按键事件的百分比(这些按键通常被保留,由系统使用,如Home、Back、Start Call、End Call及音量控制键)。
–pct-appswitch
调整启动Activity的百分比。在随机间隔里,Monkey将执行一个startActivity()调用,作为最大程度覆盖包中全部Activity的一种方法。
–pct-anyevent
调整其它类型事件的百分比。它包罗了所有其它类型的事件,如:按键、其它不常用的设备按钮、等等。
约束限制
-p
如果用此参数指定了一个或几个包,Monkey将只允许系统启动这些包里的Activity。如果你的应用程序还需要访问其它包里的Activity(如选择取一个联系人),那些包也需要在此同时指定。如果不指定任何包,Monkey将允许系统启动全部包里的Activity。要指定多个包,需要使用多个 -p选项,每个-p选项只能用于一个包。
-c
如果用此参数指定了一个或几个类别,Monkey将只允许系统启动被这些类别中的某个类别列出的Activity。如果不指定任何类别,Monkey将选 择下列类别中列出的Activity: Intent.CATEGORY_LAUNCHER或Intent.CATEGORY_MONKEY。要指定多个类别,需要使用多个-c选项,每个-c选 项只能用于一个类别。
调试
–dbg-no-events
设置此选项,Monkey将执行初始启动,进入到一个测试Activity,然后不会再进一步生成事件。为了得到最佳结果,把它与-v、一个或几个包约 束、以及一个保持Monkey运行30秒或更长时间的非零值联合起来,从而提供一个环境,可以监视应用程序所调用的包之间的转换。
–hprof
设置此选项,将在Monkey事件序列之前和之后立即生成profiling报告。这将会在data/misc中生成大文件(~5Mb),所以要小心使用它。
–ignore-crashes
通常,当应用程序崩溃或发生任何失控异常时,Monkey将停止运行。如果设置此选项,Monkey将继续向系统发送事件,直到计数完成。
–ignore-timeouts
通常,当应用程序发生任何超时错误(如“Application Not Responding”对话框)时,Monkey将停止运行。如果设置此选项,Monkey将继续向系统发送事件,直到计数完成。
–ignore-security-exceptions
通常,当应用程序发生许可错误(如启动一个需要某些许可的Activity)时,Monkey将停止运行。如果设置了此选项,Monkey将继续向系统发送事件,直到计数完成。
–kill-process-after-error
通常,当Monkey由于一个错误而停止时,出错的应用程序将继续处于运行状态。当设置了此选项时,将会通知系统停止发生错误的进程。注意,正常的(成功的)结束,并没有停止启动的进程,设备只是在结束事件之后,简单地保持在最后的状态。
–monitor-native-crashes
监视并报告Android系统中本地代码的崩溃事件。如果设置了–kill-process-after-error,系统将停止运行。
–wait-dbg
停止执行中的Monkey,直到有调试器和它相连接。-v
命令行的每一个-v将增加反馈信息的级别。Level 0(缺省值)除启动提示、测试完成和最终结果之外,提供较少信息。Level 1提供较为详细的测试信息,如逐个发送到Activity的事件。Level 2提供更加详细的设置信息,如测试中被选中的或未被选中的Activity。
事件
-s
伪随机数生成器的seed值。如果用相同的seed值再次运行Monkey,它将生成相同的事件序列。
–throttle
在事件之间插入固定延迟。通过这个选项可以减缓Monkey的执行速度。如果不指定该选项,Monkey将不会被延迟,事件将尽可能快地被产成。
–pct-touch
调整触摸事件的百分比(触摸事件是一个down-up事件,它发生在屏幕上的某单一位置)。
–pct-motion
调整动作事件的百分比(动作事件由屏幕上某处的一个down事件、一系列的伪随机事件和一个up事件组成)。
–pct-trackball
调整轨迹事件的百分比(轨迹事件由一个或几个随机的移动组成,有时还伴随有点击)。
–pct-nav
调整“基本”导航事件的百分比(导航事件由来自方向输入设备的up/down/left/right组成)。
–pct-majornav
调整“主要”导航事件的百分比(这些导航事件通常引发图形界面中的动作,如:5-way键盘的中间按键、回退按键、菜单按键)
–pct-syskeys
调整“系统”按键事件的百分比(这些按键通常被保留,由系统使用,如Home、Back、Start Call、End Call及音量控制键)。
–pct-appswitch
调整启动Activity的百分比。在随机间隔里,Monkey将执行一个startActivity()调用,作为最大程度覆盖包中全部Activity的一种方法。
–pct-anyevent
调整其它类型事件的百分比。它包罗了所有其它类型的事件,如:按键、其它不常用的设备按钮、等等。
约束限制
-p
如果用此参数指定了一个或几个包,Monkey将只允许系统启动这些包里的Activity。如果你的应用程序还需要访问其它包里的Activity(如选择取一个联系人),那些包也需要在此同时指定。如果不指定任何包,Monkey将允许系统启动全部包里的Activity。要指定多个包,需要使用多个 -p选项,每个-p选项只能用于一个包。
-c
如果用此参数指定了一个或几个类别,Monkey将只允许系统启动被这些类别中的某个类别列出的Activity。如果不指定任何类别,Monkey将选 择下列类别中列出的Activity: Intent.CATEGORY_LAUNCHER或Intent.CATEGORY_MONKEY。要指定多个类别,需要使用多个-c选项,每个-c选 项只能用于一个类别。
调试
–dbg-no-events
设置此选项,Monkey将执行初始启动,进入到一个测试Activity,然后不会再进一步生成事件。为了得到最佳结果,把它与-v、一个或几个包约 束、以及一个保持Monkey运行30秒或更长时间的非零值联合起来,从而提供一个环境,可以监视应用程序所调用的包之间的转换。
–hprof
设置此选项,将在Monkey事件序列之前和之后立即生成profiling报告。这将会在data/misc中生成大文件(~5Mb),所以要小心使用它。
–ignore-crashes
通常,当应用程序崩溃或发生任何失控异常时,Monkey将停止运行。如果设置此选项,Monkey将继续向系统发送事件,直到计数完成。
–ignore-timeouts
通常,当应用程序发生任何超时错误(如“Application Not Responding”对话框)时,Monkey将停止运行。如果设置此选项,Monkey将继续向系统发送事件,直到计数完成。
–ignore-security-exceptions
通常,当应用程序发生许可错误(如启动一个需要某些许可的Activity)时,Monkey将停止运行。如果设置了此选项,Monkey将继续向系统发送事件,直到计数完成。
–kill-process-after-error
通常,当Monkey由于一个错误而停止时,出错的应用程序将继续处于运行状态。当设置了此选项时,将会通知系统停止发生错误的进程。注意,正常的(成功的)结束,并没有停止启动的进程,设备只是在结束事件之后,简单地保持在最后的状态。
–monitor-native-crashes
监视并报告Android系统中本地代码的崩溃事件。如果设置了–kill-process-after-error,系统将停止运行。
–wait-dbg
停止执行中的Monkey,直到有调试器和它相连接
参考文档:http://www.2cto.com/kf/201306/220906.html

MonkeyRunner的使用

MonkeyRunner介绍

monkeyrunner工具提供了一个API,使用此API写出的程序可以在Android代码之外控制Android设备和模拟器。通过monkeyrunner,写出一个Python程序去安装一个Android应用程序或测试包,运行它,向它发送模拟击键,截取它的用户界面图片,并将截图存储于工作站上。monkeyrunner工具的主要设计目的是用于测试功能/框架水平上的应用程序和设备,或用于运行单元测试套件。

常用函数说明:

1) waitForConnection(3.0,’emulator-5554’) 连接设备
第一个参数为等待连接设备时间 第二个参数为具体连接的设备
2) EasyMonkeyDevice(device)    获取EasyMonkeyDevice对象
3) device.startActivity    启动activity.
不可以启动任意Activity只可以启动主Activity.
4) sleep(3.0) 设置休眠时间
在调转到其他的activity的时候,需要该activity加载完成View以后才可以进行其他的touch等事件操作。否则后出现异常。异常日志:

Monkey、MonkeyRunner自动化测试文档
5) touch(by,MonkeyDevice.DOWN_AND_UP)   easyMonkey点击事件
第一个参数书view的Id(参考6),第二个参数是事件类型。
6) By.id(“id/XXXX”)    事件点击需要
7) easyMonkey.type(by,’17021917782’) 文本输入
第一个参数参考(6)  第二个参数是要输入的文本
8) takeSnapshot()    截图函数

monkeyrunner在Dialog中的使用

函数借鉴wrapEasyMonkey的touchDialogById(id)方法:
具体的方法实现:
def touchDialogById(id,type):
hierarchyViewer = device.getHierarchyViewer()
width=device.getProperty("display.width")
height=device.getProperty("display.height")
x = hierarchyViewer.findViewById(id).left
y = hierarchyViewer.findViewById(id).top
print 'begain ------------------begain '
print hierarchyViewer.findViewById(id).scrollX
print hierarchyViewer.findViewById(id).scrollY
print hierarchyViewer.findViewById(id).marginTop
print hierarchyViewer.findViewById(id).marginLeft
print hierarchyViewer.findViewById(id).marginRight
print hierarchyViewer.findViewById(id).marginBottom
print hierarchyViewer.findViewById(id).left
print hierarchyViewer.findViewById(id).top
print hierarchyViewer.findViewById(id).width
print hierarchyViewer.findViewById(id).height

print width
print height
print hierarchyViewer.findViewById(id)
print hierarchyViewer.findViewById(id).properties
print 'end ------------------ end '
p = hierarchyViewer.findViewById(id).parent.parent
#print p.properties
myself = hierarchyViewer.findViewById(id)
content = hierarchyViewer.findViewById('id/content')
x += p.left + (int(width) - content.width)/2 + myself.width/2
y += p.top + (int(height) - content.height)/2 + myself.height/2
#( int(width) - hierarchyViewer.findViewById(id).width)/2 + hierarchyViewer.findViewById(id).left + hierarchyViewer.findViewById(id).width/2
#y += ( int(height) - hierarchyViewer.findViewById(id).height)/2 + hierarchyViewer.findViewById(id).top + hierarchyViewer.findViewById(id).height/2
device.touch(x,y,MonkeyDevice.DOWN_AND_UP)

实现原理大致是通过当前的Dialog的位置来获取坐标,然后在进行各种操作,比如EditText获取焦点然后输入文字,Button的点击事件等。(具体的实现参考order.py的脚本)该方法不适用于popupWindow.只能自己测量出popupwindow的位置信息,然后做出相关处理。

运行MonkeyRunner

启动控制台,调用SDK子目录tools中的MonkeyRunner命令。在MonkeyRunner后加入Python脚本目录。
1) 进入tools目录下。
2) 运行Monkeyrunner命令
Monkey、MonkeyRunner自动化测试文档
(Window下 )
Monkey、MonkeyRunner自动化测试文档
(linux下)

编写Python脚本

首先导入MonkeyRunner所要使用的模块。
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
之后用device = MonkeyRunner.waitForConnection(int,string)来连接设备。第一个参数为等待连接设备时间,第二个参数为连接的设备名。
启动Activity:device.startActivity(component = ‘包名+Activity名’)
根据id点击:easyMonkey = EasyMonkeyDevice(device)
easyMonkey.touch(By.id(‘控件id’),MonkeyDevice.DOWN_AND_UP)
根据坐标点点击:device.touch(x,y,MonkeyDevice.DOWN_AND_UP)
点击listview某一项:
点击listview某一项在MonkeyRunner里没有方法,可以用Hierarchy Viewer得到的控件树形图,基于每个控件所在的子节点的位置,结合python函数的不定参数的特性,去获取任意已知ID的父节点的任意子节点的引用,然后再用这个引用作为参数去获取其对应的文本、断言等等。
具体方法如下:

def getChildView(parentId, *childSeq):
hierarchyViewer = device.getHierarchyViewer()
childView="hierarchyViewer.findViewById('" + parentId +"')"
for index in childSeq:
childView += ('.children[' + str(index) + ']')
print childView
return eval(childView)

通过树形图可以找到listview中的某一项,比如
Monkey、MonkeyRunner自动化测试文档

可以逐层往上找到recyclerview的id,并且把角标记录。这样可以通过已知id的recyclerview来找到某一项。
Monkey、MonkeyRunner自动化测试文档

方法的使用方法:view= getChildView(‘控件id’,0,0,1,3,1),后面的数字是hierarchyviewer逐层的下角标。之后获取view的中心点以便点击。
获取中心点:view_point = device.getHierarchyViewer().getAbsoluteCenterOfView(view),之后可以调用点击坐标点的方法来点击该项。(point有x和y属性,对应x,y坐标)
操作dialog的方法:
为edittext输入数据:easyMonkey.type(‘et的id’,’要输入的内容’)
截图:result = device.takeSnapShot()
保存截图:result.writeToFile(‘./shot1.png’,’png’)
参考文档:http://daishaoli.blog.163.com/blog/static/163253374201462433345349/

自动化测试脚本

#coding=utf-8
#####################测试下单流程
#导入我们需要用到的包和类并且起别名
import sys
from com.android.monkeyrunner.easy import By
from com.android.monkeyrunner import MonkeyRunner as mr
from com.android.monkeyrunner import MonkeyDevice as md
from com.android.monkeyrunner import MonkeyImage as mi
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
from com.android.monkeyrunner.easy import EasyMonkeyDevice

from com.android.chimpchat.hierarchyviewer import HierarchyViewer
from com.android.hierarchyviewerlib.models import ViewNode, Window
from java.awt import Point
#connect device 连接设备
#第一个参数为等待连接设备时间
#第二个参数为具体连接的设备
device = mr.waitForConnection(3.0,'emulator-5554')
easyMonkey = EasyMonkeyDevice(device)
#得到一个HierarchyViewer对象(出现的问题)手机一般不支持from com.android.chimpchat.hierarchyviewer import HierarchyViewerfrom
# ##com.android.hierarchyviewerlib.device import ViewNode需要root权限
#hierarchy_viewer = device.getHierarchyViewer()
if not device:
print >> sys.stderr,"fail"
sys.exit(1)
#定义要启动的Activity
componentName='XXXXXX'
#启动特定的Activity
device.startActivity(component=componentName)
mr.sleep(3.0)


#写脚本时用的屏幕分辨率
standard_x = 1080
standard_y = 1920
#当前测试时用的屏幕分辨率,测试时需要根据测试机修改
current_x = 1080
current_y = 1920

def getX(x):
x = x*current_x/standard_x
return x

def getY(y):
y = y*current_y/standard_y
return y


############定义方法(结合hierarchyviewer使用)
def getChildView(parentId, *childSeq):
hierarchyViewer = device.getHierarchyViewer()
childView="hierarchyViewer.findViewById('" + parentId +"')"
for index in childSeq:
childView += ('.children[' + str(index) + ']')
print childView
return eval(childView)

#########获取确定按钮的坐标########
def getBtnPoint():
btn = getChildView('id/XXXX')
print btn
point = device.getHierarchyViewer().getAbsoluteCenterOfView(btn);
return point


##############
def takOrderWithPic():
#
jjrs = getChildView('id/XXXX',0,0,1,3,1)
print jjrs
jjrs_point = device.getHierarchyViewer().getAbsoluteCenterOfView(jjrs)
device.touch(jjrs_point.x,jjrs_point.y,MonkeyDevice.DOWN_AND_UP)
MonkeyRunner.sleep(3.0)
#
jjrs_pc = getChildView('id/XXXX',0,0,2,0,2)
print jjrs_pc
jjrs_pc_point = device.getHierarchyViewer().getAbsoluteCenterOfView(jjrs_pc)
device.touch(jjrs_pc_point.x,jjrs_pc_point.y,MonkeyDevice.DOWN_AND_UP)
device.touch(jjrs_pc_point.x,jjrs_pc_point.y,MonkeyDevice.DOWN_AND_UP)
device.touch(jjrs_pc_point.x,jjrs_pc_point.y,MonkeyDevice.DOWN_AND_UP)
#确定
easyMonkey.touch(By.id('id/XXX'),MonkeyDevice.DOWN_AND_UP)
MonkeyRunner.sleep(3.0)

#
ggdp = getChildView('id/XXX',1,0,1,3,0,0,2)
print ggdp
ggdp_point = device.getHierarchyViewer().getAbsoluteCenterOfView(ggdp)
device.touch(ggdp_point.x,ggdp_point.y,MonkeyDevice.DOWN_AND_UP)
#popup弹出
device.touch(getX(250),getY(1400),MonkeyDevice.DOWN_AND_UP)#大
device.touch(getX(734),getY(1400),MonkeyDevice.DOWN_AND_UP)#小
device.touch(getBtnPoint().x,getBtnPoint().y,MonkeyDevice.DOWN_AND_UP)#确定
#糖醋里脊 普通菜
tclj = getChildView('id/XXXX',2,0,1,3,0,0,2)
print tclj
tclj_point = device.getHierarchyViewer().getAbsoluteCenterOfView(tclj)
device.touch(tclj_point.x,tclj_point.y,MonkeyDevice.DOWN_AND_UP)
device.touch(tclj_point.x,tclj_point.y,MonkeyDevice.DOWN_AND_UP)
return ""

########操作对话框的方法1111111########
def touchDialogById(id,type):
hierarchyViewer = device.getHierarchyViewer()
width=device.getProperty("display.width")
height=device.getProperty("display.height")
x = hierarchyViewer.findViewById(id).left
y = hierarchyViewer.findViewById(id).top
print 'begain ------------------begain '
print hierarchyViewer.findViewById(id).scrollX
print hierarchyViewer.findViewById(id).scrollY
print hierarchyViewer.findViewById(id).marginTop
print hierarchyViewer.findViewById(id).marginLeft
print hierarchyViewer.findViewById(id).marginRight
print hierarchyViewer.findViewById(id).marginBottom
print hierarchyViewer.findViewById(id).left
print hierarchyViewer.findViewById(id).top
print hierarchyViewer.findViewById(id).width
print hierarchyViewer.findViewById(id).height

print width
print height
print hierarchyViewer.findViewById(id)
print hierarchyViewer.findViewById(id).properties
print 'end ------------------ end '
p = hierarchyViewer.findViewById(id).parent.parent
#print p.properties
myself = hierarchyViewer.findViewById(id)
content = hierarchyViewer.findViewById('id/content')
x += p.left + (int(width) - content.width)/2 + myself.width/2
y += p.top + (int(height) - content.height)/2 + myself.height/2
#( int(width) - hierarchyViewer.findViewById(id).width)/2 + hierarchyViewer.findViewById(id).left + hierarchyViewer.findViewById(id).width/2
#y += ( int(height) - hierarchyViewer.findViewById(id).height)/2 + hierarchyViewer.findViewById(id).top + hierarchyViewer.findViewById(id).height/2
if(type == 0):
btn = getChildView(id,0,0,4,0)
point = device.getHierarchyViewer().getAbsoluteCenterOfView(btn);
print btn
device.touch(x,y,MonkeyDevice.DOWN_AND_UP)
else :
btn = getChildView(id,0,0,4,1)
point = device.getHierarchyViewer().getAbsoluteCenterOfView(btn);
parent = btn.parent

x += 200
y += 230
print btn
print x
print y
device.touch(x,y,MonkeyDevice.DOWN_AND_UP)




########操作对话框的方法2222222##########
def touchDialogButton(type):
if type==1:
MonkeyRunner.sleep(1)
device.press('KEYCODE_DPAD_DOWN',MonkeyDevice.DOWN_AND_UP)
MonkeyRunner.sleep(1)
device.press('KEYCODE_ENTER',MonkeyDevice.DOWN_AND_UP)
if type==2:
device.press('KEYCODE_DPAD_DOWN',MonkeyDevice.DOWN_AND_UP)
MonkeyRunner.sleep(1)
device.press('KEYCODE_DPAD_RIGHT',MonkeyDevice.DOWN_AND_UP)
MonkeyRunner.sleep(1)
device.press('KEYCODE_ENTER',MonkeyDevice.DOWN_AND_UP)
if type==0:
MonkeyRunner.sleep(1)
device.press('KEYCODE_ENTER',MonkeyDevice.DOWN_AND_UP)

########输入数据#######
def writeNumber():
touchDialogById("id/content",0)
by = By.id("id/XXXX")
MonkeyRunner.sleep(1)
easyMonkey.type(by,'10')
MonkeyRunner.sleep(1)
device.press('KEYCODE_ENTER')
MonkeyRunner.sleep(1)
device.press('KEYCODE_BACK')
MonkeyRunner.sleep(1)


########点击确定按钮########
def clickSureBtn(id):
touchDialogById("id/content",1)
by = By.id("id/XXXX")
# btn = getChildView(id,0,0,4,1)
# point = device.getHierarchyViewer().getAbsoluteCenterOfView(btn);
# print btn
easyMonkey.touch(by,MonkeyDevice.DOWN_AND_UP)

#################
def operationLaid():
####touchDialogButton(2)
writeNumber()
clickSureBtn("id/content")



###################
def takeOrderWithoutPic():
#
plus_button = getChildView('id/recyclerview_no_image',3,0,2,0,0,2)
print plus_button
plus_button_point = device.getHierarchyViewer().getAbsoluteCenterOfView(plus_button)
print "plusButton :",plus_button_point.x
print "plusButton :",plus_button_point.y
device.touch(plus_button_point.x,plus_button_point.y,MonkeyDevice.DOWN_AND_UP)
device.touch(plus_button_point.x,plus_button_point.y,MonkeyDevice.DOWN_AND_UP)
#
get_ready = getChildView('id/XXXXy')
print get_ready
get_ready_point = device.getHierarchyViewer().getAbsoluteCenterOfView(get_ready)
print "getReady :",get_ready_point.x
print "getReady :",get_ready_point.y
device.touch(get_ready_point.x,get_ready_point.y,MonkeyDevice.DOWN_AND_UP)
#
device.touch(get_ready_point.x,get_ready_point.y,MonkeyDevice.DOWN_AND_UP)
#点击跳过


#循环n次
n = 2
for i in range(1,n):
#
#
merchant = getChildView('id/xRecyclerView',2)
print merchant
point = device.getHierarchyViewer().getAbsoluteCenterOfView(merchant);
print "point :",point.x
print "point :",point.y
device.touch(point.x,point.y,MonkeyDevice.DOWN_AND_UP)
#####################
print ('merchant detail ')
mr.sleep(15.0)
easyMonkey.touch(By.id("id/XXXX"),MonkeyDevice.DOWN_AND_UP)
####################
print (' XXXX ')
mr.sleep(15.0)
############
for j in range(1,21):
easyMonkey.touch(By.id("id/XXXX"),MonkeyDevice.DOWN_AND_UP)
else :
print "change order type end "

########根据不同的浏览模式执行不同的函数########
#0:有图    1(无图)#####
type = 0
if(type == 0):
takOrderWithPic()
else :
takeOrderWithoutPic()


# #############################
easyMonkey.touch(By.id("id/XXX"),MonkeyDevice.DOWN_AND_UP)
######获取确定的坐标######
point = getBtnPoint()
print ('popup show ')
mr.sleep(5.0)

device.touch(point.x,point.y,MonkeyDevice.DOWN_AND_UP)
print ('XXXX ')
mr.sleep(5.0)
##################(dialog###########
operationLaid()
mr.sleep(5.0)

easyMonkey.touch(By.id("id/XXXX"),MonkeyDevice.DOWN_AND_UP)
print "choose coupon
mr.sleep(5.0)
easyMonkey.touch(By.id("
id/XXX"),MonkeyDevice.DOWN_AND_UP)
print "
commit order"
#
mr.sleep(5.0)
easyMonkey.touch(By.id("
id/XXXX"),MonkeyDevice.DOWN_AND_UP)
print "
check order"
#
mr.sleep(5.0)
easyMonkey.touch(By.id("
id/XXX"),MonkeyDevice.DOWN_AND_UP)
print "
cancel order"
mr.sleep(5.0)
#dialog马上取消

#back键
# easyMonkey.touch(By.id("
id/back"),MonkeyDevice.DOWN_AND_UP)
# print "
back"
else:
print ('end')


mr.sleep(3.0)
result = device.takeSnapshot()

#save to file 保存到文件
result.writeToFile('./shot1.png','png');

注意事项

(1) 通过id获取view只能用在activity中,在dialog或者popupwindow中找不到。
(2) Popupwindow中的view只能通过换算分辨率比例用坐标点点击
(3) 测试的时候需要打开hierarchyviewer并连接上设备,否则找不到view报错
(4) 用真机测试时有的功能可以模拟,真机无法模拟全部功能测试。
(5) 真机一般不支持from com.android.chimpchat.hierarchyviewer import HierarchyViewer
(6) com.android.hierarchyviewerlib.device import ViewNode需要root权限
(7) 在X86下无法安装微信等APP。

5. 问题汇总

出了上面的Python的常见问题等,以下是其他的问题:
1) INSTALL_FAILED_INSUFFICIENT_STORAGE(虚拟机的问题)

Monkey、MonkeyRunner自动化测试文档
解决方案:
调整/data下空间大小(Internal Storage的大小)
Monkey、MonkeyRunner自动化测试文档
2) 无法安装微信等APP

Monkey、MonkeyRunner自动化测试文档
INSTALL_FAILED_NO_MATCHING_ABIS]
无法解决(出发换虚拟机)
这个错误提示的解决办法
是由于使用了native libraries 。该native libraries 不支持当前的cpu的体系结构。