這裏總結如何使用 monkeyrunner
來自動化測試 android apk
應用。html
python
安裝下載 python
的 msi
包,直接點擊 next
,安裝。java
java jdk
安裝由於 android sdk
這些是基於 java jvm
,因此須要須要 java jdk
環境node
android sdk
安裝使用 android sdk manager
管理工具,來安裝 android sdk tools
和 android sdk platform_tools
。這裏也須要安裝一個版本的 sdk platform
,
截圖以下:python
因爲 GWF
的緣由,使用 google
的源安裝 sdk
比較困難,咱們能夠換成國內的源。點擊這裏android
windows
下配置環境變量monkeyrunner
是 android platform_tools
中提供的一個自動化測試接口工具。能夠經過腳原本模擬 APP
業務流程。git
這裏配置github
JAVA_HOME=[你的 Java jre 文件存放根路徑] ANDROID_HOME=[你的 Android sdk 文件存放根路徑] Path=%JAVA_HOME%\bin;%JAVA_HOME%\lib;%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools;C\python
這裏這樣設置,是爲了能夠在 dos
情形下,直接執行對應的命令,如 python
, monkeyrunner
。shell
至此,環境搭建成功。windows
MonkeyRunner
是一個測試工具,經過運行 python
腳原本模擬 Android
手機界面的點擊事件來測試。通常測試步驟:api
模擬界面點擊事件 --> 事件結果截圖 --> 截圖與正確圖片比較來判斷測試結果是否經過
來一段簡單的 python
測試腳本:
# hello.py # coding: utf-8 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage # 鏈接設備 device = MonkeyRunner.waitForConnection([delay secs], [deviceid]); # 安裝APP apkFilePath = "E:/myapp.apk"; device.installPackage(apkFilePath); # 啓動 APP # 自行 google package 和 activity 是什麼 package = "com.test.myapp"; activity = "com.test.Android.myappActivity"; runComponent = package + "/" + activity; device.startActivity(component=runComponent); # 這裏通常讓腳本暫停一段時間,使得APP成功啓動起來 MonkeyRunner.sleep(3); # 下面開始模擬界面事件 # 1. 點擊事件 device.touch(x, y, "DOWN_AND_UP"); MonkeyRunner.sleep(1); # 2. 輸入事件 # 先發焦點聚焦到輸入控件上,而後 type 內容 device.touch(x, y, "DOWN_AND_UP"); MonkeyRunner.sleep(1); device.type(value); MonkeyRunner.sleep(1); # 3. 模擬按鍵按下,如後退,home按鍵按下 # 這裏第一個參數值的定義能夠 devie.press("KEYCODE_BACK", "DOWN_AND_UP"); MonkeyRunner.sleep(1); # 4. 界面滑動 device.drag((x1, y1), (x2, y2)); MonkeyRunner.sleep(1); # 點擊事件觸發,界面開始變化,截屏比較 imagetobecompared = MonkeyRunner.loadImageFromFile([image file path]); screenshot = device.takeSnapshot(); if screenshot.sameAs(imagetobecompared, 0.9): print "2張圖片相同"; else: print "2張圖片不相同";
代碼中的 KEYCODE_BACK
這樣的取值,能夠參考
按照上方測試流程,咱們須要作什麼:
正確的截圖如何獲取並保存下來
設定測試模擬器分辨率,而後獲取控件座標 (x, y)
缺陷有哪些:
來點擊控件是經過座標來肯定的,這樣在不一樣分辨率的情形下,這個座標是不同的,測試不一樣分辨率機型要寫不一樣的測試腳本
圖片的比對,這個不怎麼準確
android sdk
下提供了一些工具來幫助咱們獲取界面中控件的座標,例如 uiautomatorviewer
, hierarchyviewer
, monitor
。
這個能夠打開後,經過點擊界面上的控件,來獲取控件的座標。直接在 dos
下運行命令:
uiautomatorviewer
執行後效果圖:
這裏能夠看到 bounds
屬性的值 [256, 165][320, 223]
。這個是控件的左上和右下點的座標,能夠經過這2個點計算出中心點的座標。
獲取一個控件的座標都這麼麻煩。。。
這個工具提供了一套記錄用戶操做界面行爲的操做,例如 TOUCH
, PRESS
, TYPE
, Drag
這些操做。這個工具在 tools
或者 platform-tools
下都沒有看到,不過能夠經過代碼來調用。
# coding: utf-8 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage from com.android.monkeyrunner.recorder import MonkeyRecorder as recorder device = MonkeyRunner.waitForConnection(3, "127.0.0.1:30054"); # 啓動 recorder recorder.start(device);
啓動後的截圖以下:
點擊界面上的控件,或者 type something
, 或者 Fling
這些操做,都會在右側中留下操做記錄,這裏有點擊點的座標,
或者 type value
這些操做。
導出操做到文件中,在 py
腳本文件中,實現起來就方便了。(強烈推薦這個來記錄操做流程)
目前沒有發現比較方便快捷的截屏保存操做。因此在這裏實現了一小段截屏腳本,使用流程:
啓動模擬器,安裝APP並啓動咱們須要測試的APP
運行咱們的腳本 mkr console.py
,這裏有個 dos
窗口
在模擬器中操做APP,若是須要截屏,在步驟2中打開的 dos
窗口中輸入 save
,保存截圖
附上代碼:
mkr.bat
文件內容
@echo off monkeyrunner %~dp0%1
console.py
文件內容
# console.py # coding: utf-8 # 鏈接模擬器 ... # 這裏開始根據輸入的命令執行對應的操做 # save: 截屏並保存 png 圖片 # quit:退出 cmdstr = raw_input(">>>"); while cmdstr != "quit": # 截圖保存 if cmdstr == "save": fpng = time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png"; de.saveImage(os.path.join(pydir, "images", fpng), "png"); cmdstr = raw_input(">>>");
注:
這裏運行 raw_input
命令的時候會卡主。參考下面的 Q&A
部分,問題1。
使用空間座標來操做控件,當屏幕分辨率改變時,控件座標天然會改變。難道咱們每一個座標都寫一個測試腳本。
這裏有2種解決方式:
先固定一個屏幕分辨率,而後在新分辨率下從新計算控件座標
使用控件 id
來操做控件
方式1,假定咱們的測試腳本是在 320 * 568
分辨率下控制控件 (120, 200)
來作點擊操做。原來的代碼
device.touch(120, 200, "DOWN_AND_UP");
如今須要改成
dw = device.getProperty("display.width"); dh = device.getProperty("display.height"); nx = int(120 / 320.0 * int(dw)); ny = int(200 / 320.0 * int(dh));
另一種方式是,經過控件 id
來獲取控件,操做控件。對應的工具 hierarchyviewer
在 dos
窗口下輸入
> hierarchyviewer
運行該命令的時候,最好先把模擬器的界面調整到你須要取控件 id
的控件。上方命令成功後,會有以下截圖:
這時選中 activity
點擊 Load View Hierarchy
顯示以下界面:
這裏看到有的控件的下方有 id/content
這樣的內容,這個就是控件的 id
。
使用代碼示例以下:
# coding: utf-8 from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage from com.android.chimpchat.hierarchyviewer import HierarchyViewer from com.android.monkeyrunner.easy import By device = MonkeyRunner.waitForConnection(1, "127.0.0.1:30054"); hdevice = device.getHierarchyViewer(); # 經過id獲取node vnode = hdevice.findViewById("id/content"); # 經過node,獲取位置 point = hdevice.getAbsolutePositionOfView(vnode); pcenter = hdevice.getAbsoluteCenterOfView(vnode); # 獲取node中的文本內容 txt = hdevice.getText(vnode);
# coding: utf-8 ... from com.android.monkeyrunner.easy import EasyMonkeyDevice from com.android.monkeyrunner.easy import By # 鏈接設備,啓動APP ... easydevice = EasyMonkeyDevice(device); easydevice.touch(By.id("id/content"), MonkeyDevice.DOWN_AND_UP);
monkeyrunner
raw_input()
接收輸入後不運行後面的代碼這個被發現是 jpython
的一個 bug
, python
版本 jython-standalone-2.5.3.jar
。
當前你使用的 jpython
版本能夠在 ${ANDROID_HOME}\tools\lib
下能夠看到。
fix:
https://code.google.com/p/android/issues/detail?id=56318
adb devices
檢查不出來這裏是由於咱們要手動鏈接每天模擬器,這裏須要 ip
和 port
。
從上面的截圖,能夠看到文件夾 TianTian
, TianTian_1
, TianTian_2
...
這裏的每個文件夾內容表示一個模擬器,我這裏建立了3個模擬器,因此有三個文件夾。要鏈接哪一個模擬器,查看對應
模擬器下的鏈接 ip
地址,能夠查看下面內容:
<!--/TianTian.vbox--> <VirtualBox ...> <Machine ...> ... <Hardware ...> ... <Network> <Adapter ...> ... <NAT> ... <Forwarding name="AdbPort" proto="1" hostip="127.0.0.1" hostport="6555" guestip="10.0.2.15" guestport="5555"/> </NAT> </Adapter> </Network> </Hardware> </Machine> </VirtualBox>
這裏看到鏈接地址:hostip
, hostport
在 dos
下運行命令:
adb connect [hostip]:[hostport]
鏈接模擬器,到此 type
下面命令就能夠查詢到模擬器了。
adb devices
dos
命令 chcp
的介紹和使用,點擊這裏
顯示當前 dos
環境下的編碼格式
> chcp
切換到簡體中文編碼格式
> chcp 936
切換到英文編碼格式
> chcp 437
切換到 utf-8
編碼格式
> chcp 65001
若是在 monkeyrunner
中打印內容,報以下錯誤:
LookupError: unknown encoding 'ms936'
這個就是編碼問題,執行上面的 chcp
命令,切換咱們須要的編碼。