没有写blog习惯,整理了下去年的学习记录,贴出来希望能给他人一些启发;
MonkeyRunner简介
Monkeyrunner是用python编码实现的测试,是Monkey的升级版从随机事件流变成有逻辑的模拟用户按键、触屏、滑动操作,控制事件、随时截图。最主要是通过运行程序,在程序中提供按键或触摸事件的输入数值然后截屏,通过截屏对比是否是正常的运行。
MonkeyRunner API主要包括三个模块:
- Monkeyrunner:这个类提供了用于连接设备或者模拟器的方法。
- MonkeyDevice:这个类为安装、卸载APK,启动activity发送按键和触摸事件运行测试包的方法。
- MonkeyImage:这个类提供了截图、对比保存的方法。
MonkeyRunner特点:
编写语言:Python
运行环境:Python 环境,adb链接PC运行
测试对象:UI测试
测试限制:主要使用坐标,逻辑判断能力差
MonkeyRunner使用方法:
- 引入MonkeyRunner中所要用的模块:
from com.android.monkeyrunner
import MonkeyRunner,MonkeyDevice,MonkeyImage - 与设备链接(没有报错即链接成功)
device=MonkeyRunner.waitForConnection()
- 卸载、安装要测试的APK
device.removePackage('android-3.7.3.apk')
device.installPackage('d:/android-3.7.3.apk') - 启动任意Activity
componentName = 'com.itangyuan/.module.portlet.FlashActivity'
device.startActivity(component=componentName) - 打开菜单
device.press('KEYCODE_MENU','DOWN_AND_UP')
- 点击某一坐标点
device.touch(35,75,'DOWN_AND_UP')
- 运行截图
pic=device.takeSnapshot()
- 正确结果截图
resultTrue=MonkeyRunner.loadImageFromFile(r"d:\login.png")
- 使用.sameAs()对比两张图片,并输出对比结果True或False
print (pic.sameAs(resultTrue,0.9))
更多API参考
MonkeyRunner脚本示例:
Demo 1:
# Imports the monkeyrunner modules used by this program
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice,MonkeyImage
# Connects to the current device, returning a MonkeyDevice object
device = MonkeyRunner.waitForConnection()
# Installs the Android package. Notice that this method returns a boolean, so you can test
# to see if the installation worked.
device.installPackage('myproject/bin/MyApplication.apk')
# sets a variable with the package's internal name
package = 'com.example.android.myapplication'
# sets a variable with the name of an Activity in the package
activity = 'com.example.android.myapplication.MainActivity'
# sets the name of the component to start
runComponent = package + '/' + activity
# Runs the component
device.startActivity(component=runComponent)
# Presses the Menu button
device.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP)
# Takes a screenshot
result = device.takeSnapshot()
# Writes the screenshot to a file
result.writeToFile('myproject/shot1.png','png')
Demo 2 :
#!/usr/bin/env monkeyrunner
# -*- coding: utf-8 -*-
import time
import sys
import os
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage
#设置应用包名和入口Activity名
pakageName = 'com.new.example'
componentName = 'com.new.example/.WelcomeActivity'
#APP启动时等待时间(秒)
startTime = 5
#获取年月日时分秒
now = time.strftime("%Y-%m-%d-%H-%M-%S")
#python中获取当前运行的文件的名字
name=sys.argv[0].split("\\")
filename=name[len(name)-1]
#MonkeyRunner下获取运行的文件所在的路径
rootpath = os.path.split(os.path.realpath(sys.argv[0]))[0]
#指定位置
dir = rootpath + "/apk/"
screenPath = rootpath + "/screenShot/"
logpath = rootpath + "/log/"
#获取待测APK个数
countPak = len(os.listdir(dir))
#新建一个Log文件
if not os.path.isdir(logpath):
os.mkdir(logpath)
log = open( logpath + filename[0:-3] + "-log" +now + ".txt" , 'w')
#开始连接设备
print("Connecting...")
device = MonkeyRunner.waitForConnection()
log.write("连接设备...\n")
#卸载应用
print('Removing...')
device.removePackage(pakageName)
print ('Remove Successful!')
MonkeyRunner.sleep(2)
log.write("初始化应用环境...\n")
countOK = 0
countNO = 0
for i in os.listdir(dir):
print('Installing...<%s>'%i)
log.write("==========安装应用==========\n")
path = dir + '//' + i
#安装应用
device.installPackage(path)
print('Install Successful!')
#打开应用
device.startActivity(component=componentName)
MonkeyRunner.sleep(startTime)
log.write("启动App...\n")
#截图
result=device.takeSnapshot()
print("Take ScreenShot...")
#保存截图
result.writeToFile(screenPath + i + '.png','png')
#进行图片比较
resultTrue=MonkeyRunner.loadImageFromFile(screenPath + r'basePic.png')
print "Pic Comparing..."
log.write("对比图片中...\n")
if(result.sameAs(resultTrue,0.9)):
print("%s is OK!"%i)
log.write("比较通过!--%s--包可用!\n"%i)
#卸载应用
print('Removing...')
log.write("初始化应用环境,移除中...\n")
device.removePackage(pakageName)
print ('Remove Successful!')
log.write("==========移除完毕==========\n")
countOK += 1
MonkeyRunner.sleep(2)
else:
print("False!Please check %s!"%i)
log.write("比较失败!请检查安装包--%s--是否可用!\n"%i)
break
log.write("共测试 %s 个包,%d 个通过。"%(countPak,countOK))
MonkeyRunner脚本的执行:
CMD窗口
monkeyrunner G:\script\example.py
BAT脚本
@echo off
@echo.
@echo. =======运行脚本======
set /p a=请输入脚本名称:
start "" monkeyrunner G:\script\%a%
MonkeyRunner的录制与回放
- monkeyrecoder.py
#!/usr/bin/env monkeyrunner
# Copyright 2010, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from com.android.monkeyrunner import MonkeyRunner as mr
from com.android.monkeyrunner.recorder import MonkeyRecorder as recorder
device = mr.waitForConnection()
recorder.start(device)
- monkeyplayback.py
import sys
from com.android.monkeyrunner import MonkeyRunner
CMD_MAP = {
"TOUCH":lambda dev,arg:dev.touch(**arg),
"DRAG":lambda dev,arg:dev.drag(**arg),
"PRESS":lambda dev,arg:dev.press(**arg),
"TYPE":lambda dev,arg:dev.type(**arg),
"WAIT":lambda dev,arg:MonkeyRunner.sleep(**arg)
}
# Process a single file for the specified device.
def process_file(fp,device):
for line in fp:
(cmd,rest) = line.split("|")
try:
rest = eval(rest)
except:
print"unable to parse options"
continue
if cmd not in CMD_MAP:
print"unknown command:" + cmd
continue
CMD_MAP[cmd](device,rest)
def main():
file = sys.argv[1]
fp = open(file,"r")
device = MonkeyRunner.waitForConnection()
process_file(fp,device)
fp.close();
if __name__=="__main__":
main()
录制脚本example.py
- CMD窗口中执行命令: monkeyrunner monkeyrecoder.py
- 将生成的录制脚本保存为example.py
执行录制脚本example.py
monkeyrunner G:\script\monkeyplayback.py G:\script\example.py
作者 @new