免费云网站一键生成app,建立网站有哪些步骤,上海网页制作系统,wordpress chat一、 MonkeyRunner简介
monkeyrunner也是一款安卓sdk自有的测试工具#xff0c;开源#xff0c;位于\sdk\tools下面#xff0c;它主要做性能测试#xff0c;回归测试#xff0c;并且可以自定义测试扩展#xff0c;和monkey是完全不同的。 monkeyrunner 工具提供了一组A…一、 MonkeyRunner简介
monkeyrunner也是一款安卓sdk自有的测试工具开源位于\sdk\tools下面它主要做性能测试回归测试并且可以自定义测试扩展和monkey是完全不同的。 monkeyrunner 工具提供了一组API 通过这些 API 函数可以在Android代码之外当然也可以直接在源代码直接使用控制 Android设备和模拟器通过 monkeyrunner也可以写出一个Python脚本来安装、运行、测试、发送模拟操作流结果截图对比等等。
api: http://www.android-doc.com/tools/help/monkeyrunner_concepts.html http://android-doc.com/tools/help/monkeyrunner.html
Android Studio monkeyrunner使用: https://developer.android.com/studio/test/monkeyrunner/index.html
源码: https://android.googlesource.com/platform/sdk//6db5720/monkeyrunner/
二、 MonkeyRunner安装
JDKPython编译器 http://www.python.org/download配置环境变量 把Monkeyrunner的Tool配置到path
三、 录制、回放功能
monkeyrunner运行在PC上逐行的去解释Python脚本代码将命令发送到Android设备上戒者模拟器上执行monkeyrunner除了支持Python脚本来执行测试还可以通过录制回放的方式来执行测试。
通过monkeyrunner 脚本录制功能可以实现录制和回放功能但该功能目前提供操作徆简单只能运行比较简单的操作而且要考虑不同机器的执行效率以及操作间的时间间隔
1. 录制
录制操作
1.打开录制工具
在cmd命令行运行命令:
monkeyrunner recorder.py
即可运行recorder.py 脚本用来启动录制工具放置到sdk\tool的文件夹下recorder.py源码如下
from com.android.monkeyrunner import MonkeyRunner as mr
from com.android.monkeyrunner.recorder import MonkeyRecorder as recorder
device mr.waitForConnection()
recorder.start(device)
运行后将会看到出现这样的界面
2. 录制工具简介
会看到标题栏、手机界面、右边事件列表
按钮描述Wait设置下一条命令的等待时间Press a Button发送MENU HOME SEARCH按钮的Press Down Up事件Type Something发送一些字符串Fling模拟滑动Export Action将我们的脚本导出来Refresh Display刷新当前界面
3. 开始录制
打开了monkeyrunner recorder之后在左边的手机界面即可操作手机每一步操作都会在右边的列表生成事件 4. 录制处理
要注意的一点是录制过程中monkeyrunner不会帮你设置等待时间所以需要等待的界面要点击标题栏的wait自己添加时间等待。
WAIT|{seconds:2.0,}
操作完成之后点击Export Action把录制脚本保存为mr文件放到sdk\tool下
2. 回放
在运行回放脚本playback.py录制文件即可在手机上执行录制的操作 (ps: 这太鸡肋了) (ps2: 需要先链接好手机录制关掉)
monkeyrunner playback.py open.mr playback.py源码也是放到sdk\tools目录下
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) } def process_file(fp, device): for line in fp: (cmd, rest) line.split(|) try: # Parse the pydict 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()
四、 API和命令
1. API
三个类: - MonkeyRunner 此类提供了将monkeyrunner连接到设备或模拟器的方法。它还提供了为monkeyrunner程序创建UI和显示内置帮助的方法。 - MonkeyDevice 表示一个设备或模拟器。此类提供了用于安装和卸载包启动Activity以及向应用程序发送键盘、触摸事件、运行测试包等方法。 - MonkeyImage 这个类提供了捕获屏幕方法将位图转换为各种格式比较两个MonkeyImage对象和保存图像等方法。
2. 命令
monkeyrunner -plugin plugin_jar program_filename program_options
参数说明-plugin plugin_jar可选指定一个内含monkeyrunner的jar文件如要指定超过一个文件可以多次使用此参数。program_filename如果提供此参数 monkeyrunner作为Python程序来运行。 如果未提供参数则命令将启动交互式会话。program_options可选所指定程序的所需的参数。
具体的看上面的api网址。
五、 手工编写脚本
1. 基础
虽然 monkeyrunner 脚本使用 Python 语法编写但它实际上是通过 Jython 来解释执行。 Jython 是 Python 的 Java 实现它将 Python 代码解释成 Java 虚拟机上的字节码并执行这种做法允许在 Python 中继承一个 Java 类型可以调用任意的 Java API 。
测试脚本的一般格式:
# 在程序中引入 monkeyrunner 模块
from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice# 连接到正在运行的设备戒模拟器上返回一个 MonkeyDevice 对象
device MonkeyRunner.waitForConnection() # 安装待测应用 installPackage 会返回一个布尔值来说明安装的结果
# device.installPackage ./CalcTest.apk) # 设置要启动的活动类名有包名和活动类型组成
runComponent com.minstone.mdoctor/.activity.login.WelcomeActivity“ # 启动活动组件
device.startActivity(component runComponent)
2. UI元素访问
通过坐标是比较快的通过id定位比较慢。 坐标定位 手机不一样坐标也就不一样id定位是每个手机都一样。
方式工具说明控件坐标MR recorder 坐标获取、 其他工具获取脚本中需要对不同同分辨率兼容控件IDHierarchyViewer来解析控件ID查看ID方式为hierarchyviewer.bat工具垃圾好多手机用不了现在都用UIAutomatorViewer, 速度慢控件IDMonkeyDevice只能进行简单的常用动作
3. demo
这里我在网上找了一个例子可以看看源码学习一下
#导入我们需要用到的包和类并且起别名
import sys
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.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 #代表一个控件可获取控件属性#connect device 连接设备
#第一个参数为等待连接设备时间
#第二个参数为具体连接的设备
device mr.waitForConnection()
if not device:print sys.stderr,failsys.exit(1)#定义要启动的Activity
componentNamecom.sky.jisuanji/.JisuanjizixieActivity#启动特定的Activity
device.startActivity(componentcomponentName)
mr.sleep(5.0)#延时时间结合自身机器环境需要调整easy_device EasyMonkeyDevice(device)#初始化EasyMonkeyDevice模块必须放在startActivity之后,用来通过ID访问控件
hViewer device.getHierarchyViewer() # 对当前UI视图进行解析#执行1到9的累加操作
#1、通过坐标方式来获取
device.touch(93,241,device.DOWN_AND_UP) #1
mr.sleep(2.0)
device.touch(238,490,device.DOWN_AND_UP) #
mr.sleep(2.0)
device.touch(249,235,device.DOWN_AND_UP) #2
mr.sleep(2.0)
device.touch(238,490,device.DOWN_AND_UP) #
mr.sleep(2.0)
device.touch(370,231,device.DOWN_AND_UP) #3
mr.sleep(2.0)
device.touch(238,490,device.DOWN_AND_UP) #
mr.sleep(2.0)
device.touch(106,315,device.DOWN_AND_UP) #4
mr.sleep(2.0)
device.touch(238,490,device.DOWN_AND_UP) #
mr.sleep(2.0)
device.touch(253,323,device.DOWN_AND_UP) #5
mr.sleep(2.0)
device.touch(238,490,device.DOWN_AND_UP) #
mr.sleep(2.0)
device.touch(397,328,device.DOWN_AND_UP) #6
mr.sleep(2.0)
device.touch(238,490,device.DOWN_AND_UP) #
mr.sleep(2.0)
device.touch(96,411,device.DOWN_AND_UP) #7
mr.sleep(2.0)
device.touch(238,490,device.DOWN_AND_UP) #
mr.sleep(2.0)
device.touch(270,406,device.DOWN_AND_UP) #8
mr.sleep(2.0)
device.touch(238,490,device.DOWN_AND_UP) #
mr.sleep(2.0)
device.touch(402,423,device.DOWN_AND_UP) #9
mr.sleep(2.0)
device.touch(387,670,device.DOWN_AND_UP) #
mr.sleep(2.0)#takeSnapshot截图获取程序运行界面截图
result0 device.takeSnapshot()
#save to file 保存到文件
result0.writeToFile(./shot1.png,png);#2、通过控件ID来获取
easy_device.touch(By.id(id/qingchu),device.DOWN_AND_UP)
easy_device.touch(By.id(id/btn1),device.DOWN_AND_UP)
easy_device.touch(By.id(id/jia),device.DOWN_AND_UP)
easy_device.touch(By.id(id/btn2),device.DOWN_AND_UP)
easy_device.touch(By.id(id/jia),device.DOWN_AND_UP)
easy_device.touch(By.id(id/btn3),device.DOWN_AND_UP)
easy_device.touch(By.id(id/jia),device.DOWN_AND_UP)
easy_device.touch(By.id(id/btn4),device.DOWN_AND_UP)
mr.sleep(3.0)
#takeSnapshot截图获取程序运行界面截图
result1 device.takeSnapshot()#save to file 保存到文件
result1.writeToFile(./shot2.png,png);
if(result1.sameAs(result0,1.0)):#截图对比print(pic true)
else:print(pic false) #全图100%对比 因为时间不同会输出false#对比局部图片(去掉状态栏因为状态栏时间会改变)
pic0 result0.getSubImage((4,41,400,700)) #局部结果图形对比
pic1 result1.getSubImage((4,41,400,700))
print (pic1.sameAs(pic0,1.0)) #输出true#通过HierarchyViewer
content hViewer.findViewById(id/text) # 通过id查找对应元素返回viewnode对象来访问属性
text0 hViewer.getText(content)
print text0.encode(utf-8)#打印结果#通过By来获取
text1easy_device.getText(By.id(id/text))
print text1.encode(utf-8)#打印结果device.press(KEYCODE_BACK, device.DOWN_AND_UP)
五、 插件扩展
1. 简介
jPython的jar下载: http://www.jython.org/downloads.html MonkeyRunner.jar: 在sdk\tools 目录下 chimpchat.jar: 在sdk\tools 目录下
步骤
输入编写一个 插件启动类需实现com.google.common.base.Predicate该类在使用MonkeyRunner –plugin加载jar包时首先启动可以做一些初始化操作一般可不实现任何内容。编写插件所需实现的功能可引入%android-sdk%\tools\lib下的monkeyrunnerjython guava等以及其他的jar包进行编写将工程打包成.jar 文件在 .jar文件的manifest中添加键MonkeyRunnerStartupRunner 值为第一步的启动类完成打包。
注意事项:
插件包不能使用android SDK中的jar包。 将生成的plugin.jar文件复制到%android-sdk%\tools\lib文件夹下或修改monkeyrunner.bat文件 “-Djava.ext.dirs% frameworkdir%;% swt_path%;”这句中添加上plugin.jar文件所在文件夹路径。如果插件依赖其它jar包需要跟插件包一起复制到上面的路径中。 否则可能会提在加载或使用插件是提示 ImportError : No module named XXX 或初始化失败。
1. AS编写扩展插件
这里写一个案例: 工具: Android Studio2.2
1. 新建module
新建一个android library的module名为testplugin。
2. 导入jar
导入三个jar放到根目录的libs右击add as library即可 jPython的jar下载: http://www.jython.org/downloads.html MonkeyRunner.jar: 在sdk\tools 目录下 chimpchat.jar: 在sdk\tools 目录下
3. 编写Plugin
新建Pugin.java
package tpnet.testplugin;import com.android.internal.util.Predicate;import org.python.util.PythonInterpreter;/*** Created by LITP on 2016/10/10.*/public class Plugin implements PredicatePythonInterpreter{Overridepublic boolean apply(PythonInterpreter pythonInterpreter) {pythonInterpreter.set(tpnet,Hello world);return false;}
}新建MyTestPlugin.java
package tpnet.testplugin;import com.android.chimpchat.core.TouchPressType;
import com.android.monkeyrunner.MonkeyDevice;
import com.android.monkeyrunner.doc.MonkeyRunnerExported;
import com.android.monkeyrunner.easy.By;
import com.android.monkeyrunner.easy.EasyMonkeyDevice;import org.python.core.PyObject;/*** Created by LITP on 2016/10/10.*/public class MyTestPlugin {private MonkeyDevice device null;private EasyMonkeyDevice easy_device null;MonkeyRunnerExported(doc 根据一个 MonkeyDevice实例创建Plugin., args { device }, argDocs { 要扩展的MonkeyDevice实例. })public MyTestPlugin(MonkeyDevice device) {if(device ! null){this.device device;easy_device new EasyMonkeyDevice(device);}}MonkeyRunnerExported(doc Hello Word Test., args { }, argDocs { print \Hello World!\. })public void test(PyObject[] args) {System.out.println(Hello World!);}MonkeyRunnerExported(doc Test Reboot Phone., args { }, argDocs { Reboot MobilPhone. })public void testReboot(PyObject[] args){device.reboot(args, null);}//这个方法可以在脚本调用MonkeyRunnerExported(doc Plus 1-9., args { }, argDocs { Reboot MobilPhone. })public void plus() {easy_device.touch(By.id(id/qingchu), TouchPressType.DOWN_AND_UP);easy_device.touch(By.id(id/btn1),TouchPressType.DOWN_AND_UP);easy_device.touch(By.id(id/jia),TouchPressType.DOWN_AND_UP);easy_device.touch(By.id(id/btn2),TouchPressType.DOWN_AND_UP);}
}3. 修改gadle
修改gradle添加task下一步运行这个task即可打包jar
apply plugin: com.android.libraryandroid {compileSdkVersion 24buildToolsVersion 24.0.2defaultConfig {minSdkVersion 15targetSdkVersion 24versionCode 1versionName 1.0testInstrumentationRunner android.support.test.runner.AndroidJUnitRunner}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile(proguard-android.txt), proguard-rules.pro}}lintOptions {abortOnError false}
}dependencies {compile fileTree(include: [*.jar], dir: libs)androidTestCompile(com.android.support.test.espresso:espresso-core:2.2.2, {exclude group: com.android.support, module: support-annotations})compile com.android.support:appcompat-v7:24.2.1testCompile junit:junit:4.12compile files(libs/chimpchat.jar)compile files(libs/jython-standalone-2.7.0.jar)compile files(libs/monkeyrunner.jar)
}task deleteOldJar(type: Delete) {delete release/AndroidPlugin.jar
}//task to export contents as jar 将from(*)该目录下的文件复制到release/下 并更改名称为Bsdiff.jar
task exportJar(type: Copy) {from(build/intermediates/bundles/release/)into(release/)include(classes.jar)
//Rename the jarrename(classes.jar, AndroidPlugin.jar)}
exportJar.dependsOn(deleteOldJar, build) 4. 打包jar
在右侧的gradle找到exportJar双击运行运行完毕即可在module根目录下的realease下看到AndroidPlugin.jar文件
5. 在脚本中使用编写的插件
把生成的AndroidPlugin.jar文件拷贝到sdk\tools\lib目录下
编写脚本,导入自己的jar
# 导入自己的jar
from tpnet.testplugin import MyTestPlugin as tp
运行jar里面的方法
# 初始化自己的类
ttptp(device)
# 执行方法
ttq.plus()
六、结合批处理
集合自己编写的jar利用一个批处理来运行MonkeyRunner能自动获取当前连接的设备获取apk安装包不用修改源码。双击运行这个bat批处理即可
Test.bat
echo off
cls
rem 获取当前运行设备
adb devices devices.txt
rem 获取APK文件
dir apk /B apk.txt
rem 运行monkeyrunner 脚本
monkeyrunner myScript.py -plugin lib/plugin.jar
pause
myScript.py源码
# 导包
from tpnet.testplugin import MyTestPlugin as tp
from com.android.monkeyrunner import MonkeyRunner as mr# 定义列表
deviceslist []
snapshot []
templist []
devices []# 打开文件
f open(devices.txt)# 循环读取文件添加到templist
while True:line f.readline()if line:templist.append(line.strip())else:break;# 关闭文件流
f.close()
templist.pop()# 循环添加设备
for i in range(len(templist)):deviceslist.append(templist[i].split(\t))# 读取启动activity
fc open(componentName.txt)
complist []
while True:comp fc.readline()if comp:complist.append(comp.strip())else:break;
fc.close()# 读取apk包
fp open(apk.txt)
apklist []
while True:apk fp.readline()if apk:apklist.append(apk.strip())else:break;#输出结果
print apk list :
print apklist
print start componentName list :
print complist
print devices list:
print deviceslist# 在手机上执行
for i in range(1,len(deviceslist)):print current devices:print deviceslist[i]devices.append(mr.waitForConnection(1.0,deviceslist[i][0]))for j in range(len(apklist)):devices[i-1].installPackage(apk/apklist[j])for k in range(len(complist)):print current start activity:print complist[k]devices[i-1].startActivity(componentcomplist[k])mr.sleep(5.0)ttqtp(devices[i-1])ttq.plus()
七、 回归测试
回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。 在MonkeyRunner里面主要是通过获取上次的截图和这次的截图进行对比判断
#从本地加载shot1-1.png上一次的截图进行结果对比
result0 mr.loadImageFromFile(./shot1-1.png)
#对比局部图片
pic0 result0.getSubImage((4,41,400,700)) #局部结果图形对比
pic1 result1.getSubImage((4,41,400,700))
print (pic1.sameAs(pic0,1.0)) #输出true就是bug已经修改了false不一样就是已经修好了
ok,谢谢观看