自動 Android* 應用測試

測試是應用開發流程中的重要環節。 對於 Android,這尤其重要,由於 Android 設備彼此之間差別很大,主要體如今如下幾個方面:html

  • 屏幕尺寸和分辨率python

  • Android 版本android

  • 外形shell

  • 處理器的指令集編程

  • 是否有前置攝像頭、NFC、外置鍵盤等。緩存

您應在多臺設備上對 Android 應用進行測試。app

應用測試流程包括多種測試。 讓咱們來了解一下手動功能測試。 測試者須要認真檢查全部功能並將設備重置爲初始狀態。 測試者在每一個應用和每部設備上重複上述操做。 該流程是手動完成的,所以很是耗時。工具

自動功能測試可按計劃執行而無需額外成本。 例如,測試一個 build,天天晚上在全部設備上進行測試,早上分析結果並修復漏洞。佈局

在本文中,咱們將回顧幾種適用於自動功能測試的工具。 我僅對 Android SDK 中包括的或在開源許可協議下發布的工具進行介紹。測試

自動測試的概念

咱們的目標是將手動執行的操做自動化,以實現最大精度。 讓咱們瞭解一下這些操做。 咱們將使用多個應用和多部 Android 設備。

對於每一個應用和每部設備,咱們應按照下列步驟來操做:

  1. 在設備上安裝應用

  2. 啓動應用

  3. 使用指定方法測試應用

  4. 卸載應用

  5. 將設備重置爲初始階段

在每一個步驟中,您須要收集和分析數據,如日誌和截屏。 在下文中,咱們將討論將這些步驟自動化的工具。

控制 Android 設備

首先,您須要選擇用於運行自動化測試的電腦,並在該電腦上安裝 Android SDK。 我將以運行 Linux* 系統的臺式電腦爲例。 您須要在每臺設備上禁用鎖屏並將「進入睡眠模式的時間」調整到最大值。對於一些方法 您須要禁用屏幕方向調整。

Android SDK 中有兩種實用程序能夠控制 Android 設備: ADB 和 monkeyrunner*。 下面,我將具體介紹如何將手動測試中的操做自動化。

使用 ADB 控制 Android 設備

ADB (Android Debug Bridge)是控制 Android 設備的命令行工具。 ADB 主頁是: http://developer.android.com/tools/help/adb.html

ADB 工具位於 <android_sdk>/platform-tools/ 目錄下。您須要將該目錄存放到 PATH 環境變量下。

檢查 ADB 安裝

安裝並設置 Android SDK,而後將 Android 設備鏈接至您的電腦並運行下列命令:

adb devices

該命令將出如今全部插入的 Android 設備上。 若是設備列表不是空白,那麼 ADB 即可正常運行。

在多臺設備上運行

您須要使用「-s」參數指定 ADB 應使用哪臺設備。

adb -s [serial_number] [command]

例如:

adb -s [serial_number] logcat

設備的序列號可經過輸入 «adb devices» 命令後生成的輸出中得到。 參數 -s 支持您同時使用多臺互聯設備。

基本的 ADB 命令

在設備上打開控制檯:

adb shell

在設備上運行命令:

adb shell [command]

Android 中包含許多標準的 Linux 實用程序: ls、cat、dmesg ...

從 apk 文件安裝應用:

adb install example.apk

卸載應用:

adb uninstall [package]

從 apk 文件獲取程序包名稱:

aapt dump badging example.apk | grep "Package"

從設備將文件下載至電腦:

adb pull [path-on-device] [file]

從設備將文件上傳至電腦:

adb push [file] [path-on-device]

注:
Android 設備上的大多數目錄僅支持讀取訪問。 /sdcard (可是您沒法從該目錄下運行程序)和 /data/local/tmp 支持寫入訪問。

啓動應用:

adb shell am start -n [package]/[activity]

運行指定活動。

您能夠從 apk 文件抽取活動名稱:

aapt dump badging example.apk | grep "launchable-activity"

讀取日誌

Logcat 是從 Android 設備讀取日誌的命令。

Logcat 主頁:http://developer.android.com/tools/help/logcat.html

從設備讀取日誌(按下 Ctrl-C 解除阻止):

adb logcat

清除設備上的日誌緩存:

adb logcat -c

將日誌緩存轉儲到設備上(顯示當前的緩存內容,未阻止):

adb logcat -d

示例:

1adb logcat -c # clear the buffer log2# Action3adb logcat -d > file.log # save the current contents of the log buffer to file.log

使用 screencap 截取屏幕

screencap 實用程序將當前的屏幕內容保存爲圖形文件:

1adb shell screencap /sdcard/screen.png2adb pull /sdcard/screen.png screen.png3adb shell rm /sdcard /screen.png

screencap 實用程序可在安裝了 Android 4.x 和更高版本的手機上使用。 在低於 Android 4.x 的版本上,您可使用 monkeyrunner 來截取屏幕。

使用 ADB 運行 BASH 腳原本測試應用

腳本: app_test.sh

使用 MonkeyRunner 控制 Android 設備

monkeyrunner 工具可爲腳本提供控制 Android 設備的 API。 您可使用 monkeyrunner 編寫 Python* 腳原本安裝、啓動 Android 應用,模擬用戶操做,獲取截圖並將其保存至電腦。 Monkeyrunner 使用 Jython* 運行腳本。

monkeyrunner 主頁和 API 參考: http://developer.android.com/tools/help/monkeyrunner_concepts.html

使用 monkeyrunner 讀取日誌

File log.py:

01# coding: utf-802from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice03 04def log(fn, device):05    msg = device.shell('logcat -d')06    f_log = open(fn, 'at')07    if msg is None:08        msg = 'None'09    f_log.write(msg.encode('utf-8'))10    f_log.close()    11    device.shell('logcat -c')12 13if __name__ == '__main__':14    device = MonkeyRunner.waitForConnection()15    device.shell('logcat -c') # Clear logs buffer16    # ...17    log('example.log', device) # Write logs

開始:

monkeyrunner log.py

腳本將會把日誌寫入當前目錄下名爲「文件示例.log」的文件。

使用 MonkeyRunner 捕捉截圖

File screen.py:

1# coding: utf-82from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice3 4if __name__ == '__main__':5    device = MonkeyRunner.waitForConnection()6    image = device.takeSnapshot()7    image.writeToFile('screenshot.png','png')

開始:

monkeyrunner screen.py

腳本捕捉截圖並在當前目錄下將其保存爲名爲 filescreenshot.png 文件。

示例:使用 monkeyrunner 控制設備

腳本: monkeyrunner_test.py

開始:

monkeyrunner monkeyrunner_test.py

自動測試方法

使用 Monkey* 進行測試

試想將正在測試的設備交給一隻很是敏捷且極富創造力的猴子 — Monkey(猴子)工具的設計即是模擬這種情形。Monkey 工具是 Android SDK 的組成部分,可發送一連串的隨機用戶事件。命令行參數可指定用戶操做次數、每類事件的比率和程序包的名稱(所以,Monkey 的操做不會超出所測試應用的限度,且不會向地址簿中的任何聯繫人發送 SMS)。

Monkey 主頁上提供了諸多示例和參數列表: http://developer.android.com/tools/help/monkey.html

Monkey 工具的主要優勢是零維護成本。 並且,壓力測試還可檢測出 non-trivial 漏洞。

使用 Monkey 工具進行測試的缺點:

  • Monkey 沒法模擬複雜的工做負載,如身份驗證。 所以,應用的功能性沒法進行測試。

  • 須要複雜控制(快速反應和複雜手勢)的遊戲應在開始時完成,或不要執行該類應用的測試。

  • Monkey 發現的錯誤很難再現。

  • Monkey 沒法在測試過程當中檢查應用狀態。

對於任何應用而言,開始均可以先使用 Monkey 進行自動測試。 這種方法可爲具體應用提供充足的結果。若是測試質量較低,您須要使用其餘測試方法。

使用 MonkeyRunner 進行測試

使用 MonkeyRunner,您不只能夠開發 Android 設備控制腳本,還能夠編寫腳本在特定設備上測試應用。

優勢:

  • 靈活。

缺點:

  • 編寫腳本較複雜 — 即便是在簡單的狀況下。

開發 MonkeyRunner 須要花費很長的時間,所以一般這種方法不太理想。可是在某些狀況下可使用這種方法。

使用 getevent 和 sendevent 進行測試

Getevent 和 sendevent 實用程序支持用戶記錄事件序列並將其再現。運行這些工具不須要根許可。

優勢:

  • 在手動測試下,無需花費額外成本即可記錄事件序列(若是執行)。

  • 記錄事件序列不須要編程技能。

缺點:

  • 需單獨爲每一個應用和每部設備記錄序列。若是您更改了一個應用界面,須要從新記錄全部已記錄的操做。

  • 這種方法沒法在測試過程當中檢查應用狀態。 若是應用響應延遲(如網頁加載),測試結果將出現錯誤。

  • 演示快速、複雜的序列所需的時間比記錄的時間長。 所以,有時候這種方法不適合測試響應時間較爲關鍵的動態遊戲(dynamic game)。

記錄事件序列:

01# Record event sequence02# Do actions on the device, press Ctrl-C to finish03adb shell getevent -t > events.txt04# Convert event sequence to script05./decode_events.py events.txt > events.sh06# Load the script to the device07adb push events.sh /data/local/tmp/08# Set the permissions09adb shell chmod 755 /data/local/tmp/events.sh10# Run script11adb shell sh /data/local/tmp/events.sh

腳本: decode_events.py

在設備上再現記錄的事件序列。

使用 Robotium* 進行測試

Robotium 未包含在 Android SDK 中,可是它是在開源協議下發布的產品。 Robotium 主頁是: http://code.google.com/p/robotium/

Robotium 腳本可在應用 UI 層面而非輸入設備層面定義操做。

例如,腳本須要點擊 «OK» 按鈕。 monkeyrunner 腳本將按照「點擊屏幕點(x0, y0)」執行。 Robotium 腳本將按照「按下帶有文本「OK」的按鈕」執行。

當在界面層面描述操做時,測試腳本將不受界面佈局、界面分辨率和方向的影響。

此外,Robotium 還支持您檢查應用對操做的響應。例如,點擊 «OK» 按鈕後,將會出現帶有「Item 1」的列表項目。您還可使用 Robotium 查看列表元素的名稱。 若是您能夠在每一步以後檢查應用狀態,便很容易找到錯誤出如今哪一步。

缺點:

  • 您須要在 Java* 中爲每一個應用開發一個測試腳本。 這須要編程技巧,也較爲費時。

  • 應用界面更改後,必須從新安排事件序列。

  • 相比使用 getevent / sendevent 而言,編寫 Robotium 校本更爲困難。

通常而言,Robotium 支持您以適度的成本開發最高質量的測試案例。

測試方法比較

測試方法 優勢 缺點

Monkey — 一連串隨機用戶操做

無維護成本。
不受設備影響。
壓力測試可檢查 non-trivial 錯誤。

測試質量在不一樣的應用上會有所差別。
沒法再現缺陷報告。

Monkey 沒法在測試過程當中檢查應用狀態。

monkeyrunner — 設備控制腳本

靈活性

編寫腳本較複雜 — 即便針對簡單的應用。

getevent/sendevent — 記錄/再現用戶操做

記錄事件序列不須要編程技能。

記錄的操做序列僅可在一臺設備上以固定的界面方向執行。

應用界面更改後,必須從新安排事件序列。

這種方法沒法在測試過程當中檢查應用的狀態。

Robotium — 測試腳本 API 以驗證狀態

操做在應用 UI 層面描述。

腳本可能不會受到界面分辨率和界面方向的影響。

腳本可在一個操做後檢查應用狀態。

在 Java 編寫腳本較複雜。

若是您更改了應用界面,將須要修改腳本。

結果分析

如今,咱們須要分析在自動錯誤測試流程過程當中收集的日誌和截屏。

日誌分析

您能夠搜索一下如下的字符串:

  • I/DEBUG

  • FATAL EXCEPTION

  • WIN DEATH

您能夠在該列表中添加在手動測試中發現的錯誤消息。

截屏分析

您能夠準備一系列測試關鍵時刻的截屏,並在自動測試時將其與屏幕內容進行對比。 這能夠肯定自動測試流程是否正常運行。

將最初的截屏與應用啓動後的截屏進行對比很是有用。 它能夠在應用出現靜默故障時檢查事件。

Monkeyrunner 支持您按照指定的容錯性(百分比)對比兩個截屏:

1image1 = device.takeSnapshot()2# ...3image2 = device.takeSnapshot()4if image2.sameAs(image1, 0.1):5    print 'image1 and image2 are the same (10%)'

很遺憾,沒有 MonkeyImage API 可用於加載文件中的圖片。 您可使用,如 Python* Imaging Library 編寫一個自定義功能來對比圖片。

將設備重置爲初始狀態

您應在測試後將設備重置會初始狀態。這能夠經過下列幾種方法來實現:

  • 屢次按下 «Back» 按鈕。

  • 重啓設備。

  • 重啓 zygote 流程。

一般狀況下,第一個選項最合適。

屢次按下 Back 按鈕

使用 monkeyrunner 按 「Back」 按鈕:

1for i in xrange(0, 10):2    device.press('KEYCODE_BACK', MonkeyDevice.DOWN_AND_UP)3    time.sleep(0.5)

在實際狀況下這是較好的選擇,由於它不須要用戶實際操做。

結論

在本文中,咱們介紹了幾種針對 Android 應用的自動測試方法。 咱們回顧了自動測試方法的優勢和缺點。

此外,咱們還討論了 Android SDK 中的 Monkey 和 monkeyrunner 工具以及 Robotium 工具。

自動測試不能取代其餘類型的測試。正確的有組織的測試流程(結合包括自動測試在內的不一樣測試方法)是高質量應用開發流程的必要部分。

相關文章
相關標籤/搜索