UI Testing 翻譯

除了針對 Android 應用程序中的組件(諸如:Activty,Service,content provider)進行單元測試以外,在運行時對其用戶接口(UI)的行爲進行測試也很重要。UI 測似確保應用程序有正確的的 UI 輸出來響應用戶一系列的操做,好比一個按鍵輸入或者按工具條,菜單,對話框,圖片和其它 UI 操做。html

功能測試或者黑盒 UI 測試並不須要測試人員知道應用的內部實現細節,只需知道當用戶執行某些操做或者進行某種輸入時的輸出便可。這種方法有利於分離團隊中測試人員和開發人員的職責。java

普通的 UI 測試方法就是手工運行測試並驗證應用程序的行爲是否符合預期。可是這種方法既沉悶又耗時還容易出現偏差。更高效更可靠的方法是用測試框架軟件進行 UI 自動化測試。自動化測試建立代碼來執行測試任務(test case),測試任務覆蓋各類使用場景,這樣測試框架就能夠以一種可重複的方式自動運行這些 test case。android

Overview程序員


Android SDK 提供了下面兩個工具,來對你的應用程序進行自動化功能測試:shell

  • uiautomatorviewer - 一個用來對應用程序中組件進行掃描和分析的工具。
  • uiautomator - 一個 java 庫,其中包含了用於建立自定義 UI 功能測試的 API,和一個用來自動運行測試的運行引擎。

使用這兩個工具必須安裝下面兩個版本的 Android 開發工具:app

  • Android SDK Tools,Revision 21 or higher
  • Android SDK Platform, API 16 or higher

Workflow for the the uiautomator testing framework框架

  1. 下面是 UI 自動化測試的簡化流程:
  2. 把待測程序安裝到設備上,對應用的 UI 組件進行分析,並確保待測應用程序能夠被自動化測試框架訪問。
  3. 建立自動化測試來模擬用戶和應用之間的一系列交互。
  4. 編譯 test case 並打包爲 jar 文件,而後安裝到待測應用所在的測試設備上。
  5. 運行測試並查看測試結果
  6. 修正測試中發現的 bug 和 不足之處。

Analyzing Your Application’s UIide


在開始寫 test case 以前,這有助於咱們熟悉待測應用的 UI 組件(包括 View 和控制)。對於鏈接開發電腦上的任何 Android 設備,咱們能夠用 uiautomatorviewer 工具對其前臺 UI 進行截屏。該工具提供一個方便的可視化界面,用於查看其佈局層次以及 View 的屬性。利用這些信息,咱們接下來就能夠建立 uiautomator 測試代碼了。函數

UIAutomatorViewer

 

對待測應用程序的 UI 組件進行分析:工具

1.鏈接 Android 設備和開發電腦。

2.打開命令行窗口併到 <android-sdk>/tools/ 目錄下

3.用下面命令運行該工具:

$ uiautomatorviewer

4.點擊 uiautomatorviewer 圖形界面上的 Device Screenshot 按鈕截屏用於分析。

注意:若是你的電腦上連了多個設備,能夠經過設置 ANDROID_SERIAL 環境變量來區分它們:

a.用下面命令查看鏈接設備的 serial numbers:

$ adb devices

b.經過設置 ANDROID_SEIAL 來選擇一個設備用於測試:

Windows:

set ANDROID_SERIAL=<device serial number>

UNIX:

export ANDROID_SERIAL=<device serial number>

若是你只連了一個設備就不須要設置該值。

5.查看應用程序總 UI 屬性:

  • 在左邊的面板中移動鼠標,uiautomatorviewer 就能識別這些組件,而後你就能夠看到相應 UI 組件的屬性。組件的屬性顯示在右下角的面板中,佈局層次信息列於右上角的面板中。
  • 點擊 Toggle NAF Nodes 按鈕查看 uiautomator 測試框架不能訪問的 UI 組件,可能這些組件只有一部分屬性是可訪問的。

Preparing to Test


在開始使用 uiautomator 測試框架以前,須要完成下面的準備工做:

Load the application to a device

若是你正在閱讀該文檔,極可能待測  Android 應用程序還沒有發佈。若是你有 apk 文件的拷貝,就能夠經過 adb 工具把它安裝到測試設備上去,如何用 adb 工具安裝 APK 文件,請參考 adb 文檔。

Identify the application’s UI components

在寫 uiatomator 測試以前,首先要識別待測應用程序的 UI 組件。一般優秀應用的 UI 組件是可見的而且能夠和用戶交互的。UI 組件應該有可見的 text 標籤或者 android:contentDescription 屬性,或者二者兼具。

咱們能夠用 uiautomatorviewer 工具方便地查看待測應用中可見的屏幕對象(UI 組件)。至於如何經過該工具來分析一個應用程序的屏幕信息,請參考 Analyzing Your Application’s UI 部分。關於 Android 提供了那些經常使用的 UI 組件,請參考 User Interface

Ensure that the application is accessible

這一步,是由於 uiautomator 工具運行你的 UI 功能測試代碼依賴於 Android 框架支持輔助功能的特性。要使用 uiautomator 工具,至少應該知足一下條件:

  • 使用 android:contentDescription 屬性對 ImageButton, ImangeView, CheckBox 以及其它空間設置標籤。
  • 對於 EditText 使用 android:hint 屬性而不是 content decription 。
  • Associate an android:hint attribute with any graphical icons used by controls that provide feedback to the user (for example, status or state information).
  • 確保全部的可操做元素均可以經過方向控制器訪問,好比軌跡球或者方向鍵。
  • 經過 uiautomatorviewer 工具來確保 UI 元素能夠被測試框架訪問。咱們也能夠用打開諸如 TalkBack 和 Explore by Touch 這寫輔助服務來測試,只經過方向控制來測試咱們的應用程序。

關於實現、測試可訪問性的更多信息,請參考 Making Applications Accessible

通常狀況下,經由 View 和 ViewGroup 類,Android 程序員能夠輕易對輔助功能進行支持。可是有些應用使用自定義 view 組件以提供更好的用戶體驗。而這些自定義組件並無從標註 的 Android UI 組件那裏繼承到對輔助功能的支持。若是你的應用程序屬於這種狀況,請經過實現 AccessibilityNodeProvider 類來確保 Android 的輔助服務能夠訪問自定義 UI 組件。關於如何使自定義控件支持輔助功能,請參考 Making Applications Accessible

Configure your development environment

若是你用 Eclipse 作開發,Android SDK 另外提供了工具來幫助你編寫 uiautomator test case 並打包 jar 文件。要設置 Eclipse 以使用這些工具,須要建立一個包含 uiautomator 客戶端庫的工程,該庫通常和 Android SDK 庫在一塊兒。配置 Eclipse:

  1. 在 Eclipse 中建立一個 Java 工程並給該工程取一個名字,該名字和你即將建立的測試相關(例如:MyAppNameTests)。後面就是在該工程中建立 test case,具體建立什麼樣的 test case 取決於什麼樣的待測應用。
  2. 在 Project Explorer 視圖中,右鍵點擊剛建立的新工程,而後選擇 Properties > Java Build Path,接下來:

a. 點擊 Add Library > JUit,而後選擇 JUnit3。

b. 點擊 Add External JARs… 進入 SDK 目錄,在 platforms 目錄下,選擇最新版本的 SDK目錄,並選擇 uiautomator.jar 和 android.jar 文件。

若是你不使用 Eclipse 作開發環境,請確保你的 Java class path 包括了 <android-sdk>/platforms/<sdk> 目錄下的 uiautomator.jar 和 android.jar 文件。

這些準備工做完成後,立刻就能夠建立 uiautomator 測試了。

Creating uiautomator Tests


要構建一個能夠在 uiautomator 框架中運行的測試,首選要建立一個繼承自 UiAutomatorTestCase 的類。在 Eclipse 中這個 test case 文件屬於工程的 src 目錄。而後,會把這個 test case 構建成一個 JAR 文件,最後把這個 JAR 文件複製到測試設備中。這個 JAR 文件並非一個 APK 文件,而且和待測應用是分離的。

由於 UiAutomatorTestCase 類繼承自 junit.framework.TestCase,因此你能夠用 JUnit 的 Assert 類來測試待測應用中的 UI 組件,看是否返回指望結果。要學習更多的 JUnit 知識,你能夠閱讀 junit.org 主頁中的文檔。

test case 的首要任務是將要訪問安裝了待測應用程序的設備。先對設備的 Home screen 作測試來練練手也是一個不錯的選擇。對於 Home Screen(或者待測應用的其它位置),你能夠用 uiautomator 提供的 API 來模擬用戶的操做對特定的 UI 組件進行測試。至於如何組織一個 uiautomator test case 請看 sample test case 部分。

uiautomator API

uiautomator API 在 <android-sdk>/platforms/ uiautomator.jar 文件中,該 API 中包含如下幾個關鍵類,經過這些類咱們能夠捕獲、操做待測應用中的 UI 組件:

UiDevice

表明了設備的狀態。在測試代碼中,能夠調用 UiDevice 實例中的函數來檢測設備的各類屬性狀態,例如當前的屏幕的方向或者尺寸。也能夠經過  UiDevice 實例來執行設備層次的操做,好比強制改變設備的方向,按下 d-pad 物理按鍵或者 Home 建和菜單按鈕。

下面代碼就是獲取 UiDevice 實例,而後按下 Home 鍵:

getUiDevice().pressHome();

UiSelector

表示一個在當前顯示界面查詢、獲取特定組件的搜素條件。若是找到多個匹配組件,那麼就返回佈局層次中的第一個匹配組件,返回的是一個 UIObject 對象。構造一個 UiSelector 對象時,能夠組合多個屬性使搜索更精確。若是一個也沒找到,就會拋出一個 UiAutomatorObjectNotFoundException 異常。也能夠用 childSelector() 函數來嵌套多個 UiSelector 實例。例如,下面的示例代碼就展現瞭如何設定一個搜索條件,在當前顯示界面中找到第一個 ListView,而後在這個 ListView 中搜索一個 text 屬性爲 「Apps」的 UI 組件。

UiObject appItem = new UiObject(new UiSelector() .className("android.widget.ListView").instance(1) .childSelector(new UiSelector().text("Apps")));

UiObject

表明一個 UI 組件。建立 一個 UiObject 實例時經過一個 UiSelector 對象來搜索對應的 UI 組件。

下面的示例代碼展現瞭如何建立 UiObject 對象,這兩個對象表示應用程序中的一個 Cancel 按鈕和一個 OK 按鈕。

UiObject cancelButton = new UiObject(new UiSelector().text("Cancel")); UiObject okButton = new UiObject(new UiSelector().text("OK"));

若是須要,你能夠在測試程序的其它地方重用已經建立的 UiObject 實例。要注意的是,在測試代碼中你每次用一個 UiObject 實例對一個 UI 組件進行點擊操做或者查詢其屬性,uiautomator 測試框架都會在當前顯示界面進行一次搜索。

在下面的示例代碼中,uiautomator 測試框架會先搜索 text 屬性爲 「OK」的 UI 組件,若是存在而且是 enable 的,那麼測試框架就會模擬用戶對該組件進行點擊操做。

if(okButton.exists() && okButton.isEnabled()) { okButton.click(); }

也能夠限制搜索條件只搜索特定類的組件。例如,搜索 Button 類的組件:

UiObject cancelButton = new UiObject(new UiSelector().text("Cancel") .className("android.widget.Button")); UiObject okButton = new UiObject(new UiSelector().text("OK") .className("android.widget.Button"));

UiCollection

表明組件的集合,例如一個視頻專輯或者收件箱。實例化 UiCollection 和實例化 UiObject 相似都要傳一個 UiSelector 進去。對於 UiCollection,UiSelector 用於搜索多個子控件的容器(例如:一個包含子控件的 Layout)。例如,下面的代碼片斷展現瞭如何建立一個表明一個視頻專輯的 UiCollection,該專輯顯示在一個 FrameLayout 中:

UiCollection videos = new UiCollection(new UiSelector() .className("android.widget.FrameLayout"));

若是這些視頻都顯示在一個 LinearLayout 中,你又想獲取這些視頻的個數:

int count = videos.getChildCount(new UiSelector() .className("android.widget.LinearLayout"));

若是你要從中找出一個 text 屬性爲 「Cute Baby Laughting」的視頻,並模擬用戶去點擊它:

UiObject video = videos.getChildByText(new UiSelector() .className("android.widget.LinearLayout"), "Cute Baby Laughing"); video.click();

對於這個 UI 對象上你一樣能夠模擬其它的用戶操做。例如,你能夠模擬選擇一個與某一視頻線關聯的 checkbox:

UiObject checkBox = video.getChild(new UiSelector() .className("android.widget.Checkbox")); if(!checkBox.isSelected()) checkbox.click();

UiScollable

表明一個可滾動的 UI 組件集合。你能夠用 UiScrollable 來模擬 UI 組件的垂直或者水平滾動。當一個 UI 組件顯示在屏幕之外,你須要滾動才能看到它,這時候這個技術就頗有用。

例以下面的示例代碼演示如何模擬向下滾動設置菜單並點擊一個 About tablet 的選項:

UiScrollable settingsItem = new UiScrollable(new UiSelector() .className("android.widget.ListView")); UiObject about = settingsItem.getChildByText(new UiSelector() .className("android.widget.LinearLayout"), "About  tablet"); about.click()

關於這些 API 的更多信息請參考 uiautomator

A sample uiautomator test case

下面的示例代碼是一個簡單的 test case,它模擬用戶在一個通用 Android 設備上進行設置應用程序的操做。該 test case 模擬用戶執行這個任務一般會作的全部操做,包括打開 Home Screen,打開 All Apps Screen,滾動找到 Settings app 的圖標,而後點擊這個圖標進入設置界面。

package com.uia.example.my; // Import the uiautomator libraries
import com.android.uiautomator.core.UiObject; import com.android.uiautomator.core.UiObjectNotFoundException; import com.android.uiautomator.core.UiScrollable; import com.android.uiautomator.core.UiSelector; import com.android.uiautomator.testrunner.UiAutomatorTestCase; public class LaunchSettings extends UiAutomatorTestCase { public void testDemo() throws UiObjectNotFoundException { // 模擬點擊 HOME 按鈕.
 getUiDevice().pressHome(); // 如今在 Home Sceen. 接下來咱們模擬用戶進入 All Apps 屏 // 若是用 uiautomatorviewer 工具對 Home Screen 進行截圖分析// 就會發現 All Apps 按鈕的 content-description 屬性的值是 「Apps」 // 咱們能夠用這個屬性值建立一個 UiSelector 來找到這個按鈕。
      UiObject allAppsButton = new UiObject(new UiSelector() .description("Apps")); // 模擬進入 All Apps 屏
 allAppsButton.clickAndWaitForNewWindow(); // 設置按鈕在 All Apps 屏的 「Apps tab」 中。咱們建立一個 UiSelector 找到 // text 屬性是 「Apps」 的 tab ,而後模擬用戶點擊進入 Apps tab。
      UiObject appsTab = new UiObject(new UiSelector() .text("Apps")); // 模擬點擊進入 Apps tab
 appsTab.click(); // 接下來在 Apps tab 中模擬用戶滑動屏幕找到設置程序的圖標。 // 由於這個 Apps tab 是能夠滑動的,因此咱們能夠用一個 UiScrollable 對象。
      UiScrollable appViews = new UiScrollable(new UiSelector() .scrollable(true)); // 設置爲水平滑動模式(模式是垂直滑動)
 appViews.setAsHorizontalList(); // 建立一個 UiSelector 找到設置按鈕, // 而後模擬用戶點擊加載這個程序 
      UiObject settingsApp = appViews.getChildByText(new UiSelector() .className(android.widget.TextView.class.getName()), "Settings"); settingsApp.clickAndWaitForNewWindow(); // 驗證它的 package name 是否符合預期。
      UiObject settingsValidation = new UiObject(new UiSelector() .packageName("com.android.settings")); assertTrue("Unable to detect Settings", settingsValidation.exists()); } }

Building and Deploying Your uiautomator Tests


完成測試代碼以後,根據下面步驟來 build 並把 JAR 文件部署到測試機上:

  • 建立 build 配置文件用來生成 JAR。打開終端而後運行下面命令來生成 build 配置文件:
<android-sdk>/tools/android create uitest-project -n <name> -t 1 -p <path>

<name> 是包含 uiautomator 測試源代碼的工程名字,<path> 是項目文件夾的路徑。

  • 從命令行設置 ANDORID_HOME 變量:

Windows:

set ANDROID_HOME=<path_to_your_sdk>

UNIX:

export ANDROID_HOME=<path_to_your_sdk>
  • 進入工程文件夾,build.xml 文件就在這裏。而後 build 生成 JAR 文件。
ant build
  • 用 adb push 命令把生成的 JAR 文件部署到測試機
adb push <path_to_output_jar> /data/local/tmp/
下面是一個例子
adb push ~/dev/workspace/LaunchSettings/bin/LaunchSettings.jar /data/local/tmp/

Running uiautomator Tests


下面的例子是展現如何運行 LaunchSettings.jar 測試代碼。該測試位於 com.uia.example.my 包中:

adb shell uiautomator runtest LaunchSettings.jar -c com.uia.example.my.LaunchSettings

關於 uiautomator 的語法、命令、設置的詳細信息請參考 uiautomator

Best Practices


下面是一些用 uiautomator 框架進行 UI 功能測試的最佳實踐:

  • 一樣的 UI 功能,要在儘量多的設備上進行測試(例如不一樣屏幕密度的設備)。
  • 同時, 也應該測試一些常規的場景,例如,來電話的時候,斷網的狀況,切換其它應用的狀況。
相關文章
相關標籤/搜索