2012年10月17日 星期三

Android MonkeyRunner 和 Jythan - 從一個簡單的範例開始

English Version


MonkeyRunner是由Google Android開發團隊所提出的控制Android的工具,放置於Android SDK。
MonkeyRunner 是由一組控制命令並使用Jython的語法來做控制程序的撰寫。Jython是由Java虛擬機器來執行,有別於Python是用C/C++來做執行。利用Jython來作邏輯控制將會更有彈性的控制Android裝置。

在閱讀本篇文章前,你需要對MonkeyRunner的設定環境先行了解。若尚不知怎麼作,可以先閱讀此篇文章 http://android-test-tw.blogspot.com/2012/10/android-automation-test-by-monkeyrunner.html

Jython簡介

在開始介紹如何用Jython來撰寫MonkeyRunner的Script前,我們先來介紹基本的Jython語法。

Jython可使用的變數類別有數字、字串和串列。使用變數不需要宣告,主要是依據指定的值的型態來確認變數的類別。

接下來先來看幾個簡單的範例方便快速了解Jython的使用。你可以複製以下範例到一個文字檔。例如example.py。打開一個cmd的視窗並執行命令 - monkeyrunner.bat example.py 再按下確定(Enter)按鈕。

設定數字給變數
num = 1
設定字串給變數
str = "Hello"
str = 'Hello2'
設定一個串列給變數
list = ['mail','inbox',100,200]

以下來簡單探討邏輯判斷與迴圈控制

使用if的方式如下所示
if_stmt ::=  "if" expression ":" suite
             ( "elif" expression ":" suite )*
             ["else" ":" suite]

範例:
if num < 0:
         num = 0
         print('Negative changed to zero')
    elif num == 0:
         print('Zero')
    elif num == 1:
         print('Single')
    else:
         print('More')


使用while的方式如下所示
while_stmt ::=  "while" expression ":" suite
                ["else" ":" suite]

範例:
num = 100
go = True

while go:
    getNum = int(raw_input('Input a number : '))
    if getNum == num:
        print 'That is right.'
        go = False
    else:
        print 'Oh No~'
else:
    print 'Game over.'
print 'Done'

使用for的方式如下所示
for_stmt ::=  "for" target_list "in" expression_list ":" suite

              ["else" ":" suite]
範例:
for i in range(9):
print(i)
else:
 print 'done'

一個簡單的加入Jython控制的MonkeyRunner範例介紹:

這個範例中,我們想要驗證執行中的畫面與我們事先設定好的畫面是否一致,以做為測試判斷的結果。在這個範例中,我們會利用Jython增加邏輯敘述到MonkeyRunner。Jython的語法基本上和Python大致相同。因此可以參考Python的語法來做為新添加的元素。

在以下的範例我們會判斷藍牙的開啟狀況,利用使用者介面來做測試結果的判斷。反覆的開關藍芽的電源。當中會需要一個API是官網未提出的。但經實驗證實可以使用。該API為MonkeyRunner.loadImageFromFile(Full_File_Path)。

首先必須先取得預設希望得到的預期測試結果的圖像,可利用以下的Script來取得。以下為片段程式碼。使用前還是需要先預載MonkeyRunner相關的類別與設定變數。

result = device1.takeSnapshot()
result.getSubImage ((133,85,85,28))
result.writeToFile('./capture1.png','PNG')

執行前請先把Android裝置的畫面選到設定,並開啟藍芽電源。這個範例使用Android JB模擬器,螢幕解析度為240X432的大小。執行上述Script後會得到以下的圖檔。
capture1.png
完整範例:
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage
#Import class of MonkeyRunner, MonkeyDevice, and MonkeyImage.
device1 = MonkeyRunner.waitForConnection(10000,"emulator-5554")
print 'connected'
#Connect Android device from computer and assign handler to variable -device1.
monkeyimage1 = MonkeyRunner.loadImageFromFile('./capture1.png')
print 'capture1.png loaded'
#Load a existing image file by load image API and assign handler to variable - monkeyimage1;
device1.press('KEYCODE_HOME','DOWN_AND_UP',' ')
print 'home key are triggered'
#Send home key event to bring up Launcher
MonkeyRunner.sleep(3);
#Wait for reaction of Android device
device1.press('KEYCODE_MENU','DOWN_AND_UP',' ')
#Send menu key event
MonkeyRunner.sleep(3);
#Wait for reaction of Android device
device1.touch ( 95, 417, "DOWN_AND_UP")
#Touch system settings in menu list
MonkeyRunner.sleep(3);
#Wait for reaction of Android device
for i in range(1000):
   device1.touch ( 197, 96, "DOWN_AND_UP")
   #Touch bluetooth On
   MonkeyRunner.sleep(2);
   monkeyimage2 = device1.takeSnapshot()
   #Take a screenshot on Android device and assign handler to variable monkeyimage2
   monkeyimage2 = monkeyimage2.getSubImage ((133,85,85,28))
   #Get specified rectangle from screenshot got by last step for the result we want to check and assign handler to variable monkeyimage2 again.
   if monkeyimage2.sameAs ( monkeyimage1, 1 ):
      print str(i+1)+':pass'
   else:
      print str(i+1)+':fail'
   #Compare the result if both images of pre-loaded and run-time screenshot are the same. 
   device1.touch ( 155, 95, "DOWN_AND_UP")
   #Touch bluetooth Off
else:
   print 'done'

測試結果若都通過,命令列視窗會顯示第幾次測試,結果為何。

參考資料:
Python Script Language Tutorial, http://docs.python.org/tutorial/
Jython Script Lanuage Tutorial, http://www.jython.org/docs/index.html
MonkeyRunner, http://developer.android.com/tools/help/monkeyrunner_concepts.html
Android KeyCode, http://developer.android.com/reference/android/view/KeyEvent.html

11 則留言: