android實用測試方法之Monkey與MonkeyRunner

monkey 的使用

monkey的簡單操作:

 Monkey的智力就是一個三歲小孩的水平,所以,使用起來也是非常簡單,當然,也做不了什麼複雜的東西

adb shell monkey [options] <event-count>

event-count

這個是配置monkey的設置,

例如, options是指定啓動那個包,不指定將會隨機啓動所有程序。

     event-count是指定隨機事件的執行次數。

這個是讓monkey發送多少次事件

實例:

我們驗證程序在隨機1000次事件中,能不能正常運行下去:

 adb shell monkey -p your.package.name -vvv 1000 > monkey1000.txt

這裏應當注意:

your.package.name --> 就是你要測試的應用的包名;

1000              --> 就是你要執行的次數;

monkey1000.txt    --> 你要將執行結果保存到哪裏(要注意的是指明絕對路徑)。

-v 爲 verbose的縮寫,就是詳細輸出事件等級,這個3個v就是輸出等級1至3的所有事件,然後再使用管道命令將輸出結果放到一個文本里面方便查看.接下來就是看你的程序能不能在這樣的折騰下堅持下去了.

 

以上截個圖看看吧

九個事件及百分比控制

1、九個事件

--pct-touch <percent> 0
調整觸摸事件的百分比(觸摸事件是一個down-up事件,它發生在屏幕上的某單一位置)(——點擊事件,涉及down、up)

--pct-motion <percent> 1
調整動作事件的百分比(動作事件由屏幕上某處的一個down事件、一系列的僞隨機事件和一個up事件組成) (——注:move事件,涉及down、up、move三個事件)

--pct-trackball <percent> 2
調整軌跡事件的百分比(軌跡事件由一個或幾個隨機的移動組成,有時還伴隨有點擊)--(軌跡球)

--pct-nav <percent> 3
調整“基本”導航事件的百分比(導航事件由來自方向輸入設備的up/down/left/right組成)

--pct-majornav <percent> 4
調整“主要”導航事件的百分比(這些導航事件通常引發圖形界面中的動作,如:5-way鍵盤的中間按鍵、回退按鍵、菜單按鍵)

--pct-syskeys <percent> 5
調整“系統”按鍵事件的百分比(這些按鍵通常被保留,由系統使用,如Home、Back、Start Call、End Call及音量控制鍵)

--pct-appswitch <percent> 6
調整啓動Activity的百分比。在隨機間隔裏,Monkey將執行一個startActivity()調用,作爲最大程度覆蓋包中全部Activity的一種方法。(從一個Activity跳轉到另一個Activity)

--pct-flip <percent> 7
調整“鍵盤翻轉”事件的百分比。

--pct-anyevent <percent> 8
調整其它類型事件的百分比。它包羅了所有其它類型的事件,如:按鍵、其它不常用的設備按鈕、等等。

紅色的數字對應下面百分比對應的數字。比如下圖中0:15.0%,表示分配--pct-touch事件15%。測試100次分配15次測試down-up。

2、百分比控制

如果在monkey參數中不指定上述參數,這些動作都是隨機分配的,9個動作其每個動作分配的百分比之和爲100%,我們可以通過添加命令選項來控制每個事件的百分比,進而可以將操作限制在一定的範圍內。

我們先來看一下不加動作百分比控制,系統默認分配事件百分比的情況

命令:adb  shell monkey -p com.android.email -vvv 100  結果:

 

再看一下指定事件,控制事件百分比之後的情況

命令:adb  shell monkey -p com.android.email --pct-anyevent 100 -vvv 100

結果:

 

說明:--pct-anyevent 100 表明pct-anyevent所代表的事件的百分比爲100%。

在monkey測試中常用的命令組合有

1、monkey -p com.yourpackage -v 500 簡單的輸出測試的信息。
2、monkey -p com.yourpackage -v -v -v 500  以深度爲三級輸出測試信息。
3、monkey -p com.yourpackage --port 端口號 -v 爲測試分配一個專用的端口號,不過這個命令只能輸出跳轉的信息及有錯誤時輸出信息。
4、monkey -p com.yourpackage -s 數字 -v 500 爲隨機數的事件序列定一個值,若出現問題下次可以重複同樣的系列進行排錯。
5、monkey -p com.yourpackage -v --throttle 3000 500 爲每一次執行一次有效的事件後休眠3000毫秒。

 

Moneky Test Log 簡單分析:

 

 /*表示跳轉到com.android.email裏面的Welcome這一個Activity裏。*/

 

 /*允許此Intent跳轉。*/

 

/*拒絕次Intent跳轉,因爲它是跳轉到非它自己的包的Activity,本測試中是指寫測試它程序所在的包,此跳轉是跳出本程序,進入到zhibo8中。*/

 

 /*發送的一些動作,如點擊按下,點擊放開,移動。 */

 

 

/*事件注入次數 100次*/

 

 /*丟棄的,鍵=0,指針=0,軌跡球=0,輕擊=0,翻轉=0。*/

 

/*網絡統計經過時間爲2556ms,其中0ms是用於在手機上的,2556ms用於無線網絡上,沒有連接的時間爲0ms。*/

 

/*monkey結束*/

 

monkey使用時常會遇到的錯誤:

1 error: device not found

 

如果你用的是模擬器這說明你的模擬器沒有啓動成功,需要重啓模擬器;如果你的是真機測試,只需將USB重插就行了(但要確保開發者模式-->USB調試已開啓)。

然後運行:adb devices  命令行查看是否有設備連接成功。 如下圖:

 

2 error: more than one device and emulator

 

錯誤說明是有一個以上的設備和仿真器。這是因爲我啓用了模擬器,同時我也將我的手機通過USB線連接到了電腦。所以這裏存在兩個設備。

不信我們可以試試,運行:adb devices 如下圖:

 

這種情況下,需要指定連接某一個設備或者模擬器就行了。

命令行運行:adb -s 1494ab93 shell monkey -p com.android.email -vvv 100

-s是關鍵字,當有多臺設備連接時,使用-s指明你測試要使用的設備。如下圖:

 

monkeyrunner的使用

錄製和回放:

1 將以下代碼存儲爲monkey_recorder.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)

 

2 將以下代碼存儲爲recorder_playback.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:

            # 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]

    

    device = MonkeyRunner.waitForConnection()

    for i in range(1000):

        fp = open(file, 'r')

        i=i+1

        print i

    

        process_file(fp, device)

        fp.close();

 

if __name__ == '__main__':

main()

3 啓動安卓模擬器。

4 打開cmd,輸入命令monkeyrunner (絕對路徑)monkey_recorder.py ,會顯示如下界面:

 

 

5 錄製腳本

⑴、錄製功能說明

wait: 用來插入下一次操作的時間間隔,點擊後即可設置時間,單位是秒;

Press a Button:用來確定需要點擊的按鈕,包括menu、home、search,以及對按鈕的press、  down、up屬性(備註:按鈕可以自定義,目前工具提供的只有以上幾個按鍵,其它按鍵需要時,在腳本中可編輯;

Type Something:用來輸入內容到輸入框;

Fling:用來進行拖動操作,可以向上、下、左、右,以及操作的範圍;

Export Actions:用來導出腳本;

Refresh Display:用來刷新手機界面,估計只有在斷開手機後,重新連接時纔會用到。

⑵、開始錄製,例如:錄製一個計算器壓力測試腳本

測試機保持在待機界面,工具同步顯示待機界面,爲保證腳本能更好的運行,一般在每個動作之間建議加一個wait 1秒的動作,點擊wait,輸入1秒

錄製界面如下圖:

 

 

 

 

 

 

 

錄製完成點擊Export Actions導出腳本,保存爲無後綴文件,如下圖:

 

將導出腳本文件後綴改爲 .py文件,如下圖:

 

6 腳本回放

首先我們需要更改回放腳本循環次數,打開recorder_playback.py文件,找到以下語句,其中數據可以更改爲任意你想要執行的次數,修改成功後保存,現在以1000爲例

 

 

打開cmd,輸入命令monkeyrunner (絕對路徑)recorder_playback.py(空格)(絕對路徑)test.py,會顯示如下界面:

 

monkeyrunner多設備測試:

接下來用一段典型的monkeyRunner代碼講解!

注意!如果monkeyrunner腳本文件要使用中文,記得格式保存爲utf8,不然會ASCII無法支持錯誤

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

#導入我們需要用到的包和類並且起別名

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

 

#connect device 連接設備

#第一個參數爲等待連接設備時間

#第二個參數爲具體連接的設備

device = mr.waitForConnection(1.0,'emulator-5554')

if not device:

    print >> sys.stderr,"fail"

    sys.exit(1)

#定義要啓動的Activity

componentName='kg.monkey/.MonkeyActivity'

#啓動特定的Activity

device.startActivity(component=componentName)

mr.sleep(3.0)

#do someting 進行我們的操作

#輸入 a s d

device.type('asd')

#輸入回車

device.press('KEYCODE_ENTER')

#return keyboard 點擊返回用於取消等下看到截圖的下方的白條

#device.press('KEYCODE_BACK')

#------

#takeSnapshot截圖

mr.sleep(3.0)

result = device.takeSnapshot()

 

#save to file 保存到文件

result.writeToFile('takeSnapshot\\result1.png','png');

 

以上代碼就是用monkeyrunner 實現操作特定操作以後,並且截圖的功能,看上去貌似挺麻煩的…如果你有很多設備要一起測試,你就會發現以上代碼是多麼爽丫丫的事情.這個腳本的實質就是一個python腳本,懂點,python的朋友,可以利用這個實現非常強悍的功能.

補充一點:如果我們要進行多設備測試怎麼辦呢?

我們可以打開recorder_playback.py文件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

import sys

from com.android.monkeyrunner import MonkeyRunner

 

# The format of the file we are parsing is very carfeully constructed.

# Each line corresponds to a single command.  The line is split into 2

# parts with a | character.  Text to the left of the pipe denotes

# which command to run.  The text to the right of the pipe is a python

# dictionary (it can be evaled into existence) that specifies the

# arguments for the command.  In most cases, this directly maps to the

# keyword argument dictionary that could be passed to the underlying

# command. 

 

# Lookup table to map command strings to functions that implement that

# command.

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:

            # 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()

多設備連接實例

def main():

device1 = MonkeyRunner.waitForConnection(5.0, '1123456789ABCDEF')

if not device1:

print("device1 connection fail")

else:

print("device1 connection success")

device2 = MonkeyRunner.waitForConnection(5.0, '0123456789ABCDEF')

if not device2:

print("device2 connection fail")

else:

print("device2 connection success")

device1.startActivity(component="com.aliyun.wireless.vos.appstore/com.aliyun.wireless.vos.appstore.SlideActivity")

MonkeyRunner.sleep(5)

device2.startActivity(component="com.android.settings/com.android.settings.Settings")

 

if __name__ == "__main__":

main()

 

注意:(1)5.0是非常有必要加的,它不是指執行多久,而是多久才執行。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章