• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 史上最簡單Robotium跨進程操作實踐——基于ADB框架

    發表于:2015-01-20來源:測試之美作者:測試之美點擊數: 標簽:Robotium
    Robotium是Android平臺下一款非常優秀的自動化測試框架,它做android平臺自動化的優勢想必看到這篇文章的人應該都很清楚。但優點歸優點,缺點也比較多,最明顯的缺點有兩個,一是必須

      Robotium是Android平臺下一款非常優秀的自動化測試框架,它做android平臺自動化的優勢想必看到這篇文章的人應該都很清楚。但優點歸優點,缺點也比較多,最明顯的缺點有兩個,一是必須要和被測系統簽名保持一致,二是不能做任何跨進程的操作。

      很多小伙伴知道怎么用robotium,也知道它有這些限制,但不知道其中的原因。這里簡單地說一下,robotium的這些先天不足的主要原因是由于它本身是基于instrumentation機制的,這既有好處也有壞處。好處是通過instrumentation注入到被測進程,從而與被測進程運行在同一進程空間,使得它能夠非常方便地識別被測應用中的被測對象,并對這些對象進行操作。壞處是既然robotium已經跟被測應用”合體”了,那么根據android的進程隔離機制,它自然也被系統隔離在其他進程之外,無法跨進程操作任何對象,如圖(1)所示。

      圖(1)Android進程沙箱示意圖

      其實使用相同的簽名對于單應用的測試來說并不是難事,網上有很多應用重簽名的方法和工具供大家使用。但不能跨進程操作確實成為了robotium最大的軟肋,很多第三方的應用測試或多或少都有一些跨進程操作的測試場景,所以不少人因為這個問題而放棄了robotium,甚是可惜啊。

      作為robotium的鐵桿粉之一(我最開始接觸android自動化測試就是用的robotium),斷斷續續用了好幾年,一直覺得是android平臺最好用的自動化測試工具之一。對于robotium怎樣突破進程的限制也做過一些研究,網上比較多的解決方案無外乎有以下幾種:

      1. 自己寫服務做server,基于AIDL或編寫socket與monkeyserver進行通訊,然后在robotium測試腳本里調用接口方法來間接地進行跨進程的操作,這種方式可以參考下這篇文章的例子:http://www.robotium.cn/archives/584 。文章的作者只是給出了思路,我自己曾經按照這種方法去實現過,發現該方法的優勢是比較穩定,缺點就是實現起來確實比較復雜,而且有些操作無法找到現成的系統aidl接口來進行操作,比如調用拍照操作,所以其實例子并不是很多,技術上的局限性較大。

      2. 基于廣播和service服務。這種方法的實現方式可以參考http://www.kjueaiud.com/ceshi/open/kygncsgj/2013/0507/206229.html 這篇文章的描述。這種方法我沒有親自去試過,但不難發現這種方法原理稍微簡單些,但該方法貌似需要系統簽名,而且自己寫廣播和服務來調用系統api,難度也不算小,所以一般不建議使用這種方式。

      綜合上面的這些跨進程的解決方案,其實都感覺不太理想,對于很多初學者來說不是太難實現就是局限性比較大,一直沒有找到一個比較理想的解決方案。直到后來在testerhome上看到一個技術很牛的兄弟把常用的adb命令做了一個很完備的封裝(PS:真的是很全了,至少常用的adb命令都在,我甚至之前都沒有想過adb命令還能做這么多事情),做成了一個獨立的測試輔助工具。我就突然聯想到為何不能使用adb命令來輔助robotium進行跨進程操作呢?既然該框架已經封裝了基于adb的所有操作,而且adb又是不受系統限制的,那么基于這個框架理論上進行跨進程操作是沒有任何問題的。后來經過試驗,確實效果不錯,輕量級、操作簡單、使用方便,并且輕松跨進程,真是居家測試、屌絲逆襲的必備神器啊。好了,閑話不多說了,接下來我們就來詳細地看看究竟是怎么用的。

      先來簡單地介紹下這個adb命令框架的常用接口。這個框架里有三個主要的包,分別介紹如下:

      xuxu.autotest這個包里面主要有兩個類,一個是AdbDevice,封裝了功能測試中常用的一些操作,如獲取當前activity的名稱和包名、獲取設備分辨率、關閉應用、點擊對象等常用功能,非常實用。另一個類是XuImage,顧名思義,即封裝了一些常見的圖片操作,如得到指定邊界的圖片截圖、對比圖片是否一致、截取圖片等。

      xuxu.autotest.element這個包主要用于獲取被測對象,主要是封裝了一個Position對象,用于通過Class Name、Id、Contentdesc等屬性來獲取一個被測對象,其底層是通過uiautomator來dump 當前ui的xml文件的,可以獲取到所有對象節點的xml文件。

      xuxu.autotest.utils這個包里面主要提供了對Date日期時間的操作,ImageUtil對圖片的操作及正則表達式和shell語句的操作的封裝,方便大家的使用??偟膩碚f整個框架的接口設計還是非常齊全的,可以實現很多常用功能,具體功能大家可以自己看源碼和幫助文檔來摸索。

      接下來就進入我們本次的主題——跨進程。為了方便大家理解,我會在本文中選擇兩個非常常見的跨進程操作場景來說明如何跨進程,也就是大家喜聞樂見的相機拍照和打電話來進行演示。

      例子1、跨進程操作之相機拍照。

      被測程序非常簡單,程序界面截圖如下圖(2)所示:

      圖(2)

      點擊第一個界面的“拍照片”按鈕后,進入界面2,點擊其中的“拍張照片”后啟動系統的相機,當用戶按下拍照功能鍵后,系統可以將用戶拍下的照片顯示在應用中,以備后續瀏覽或者是上傳。由于相機應用和我們所寫的被測應用是兩個不同的應用,所以這就屬于典型的跨進程操作,Robotium框架本身是無法對這個相機界面進行操作的。

      接下來看看關鍵的測試工程怎么創建的。測試工程的創建方法非常簡單,操作步驟如下:

      1. 首先按照常規的android測試工程的建法,創建一個常規測試工程。

      2. 在工程中引入robotium和adbForAndroid的jar包。

      這樣,我們的測試工程就準備好了。

      接下來的步驟就是寫測試腳本。由于AdbForAndroid框架是按照元素的相關屬性來查找并定位被測對象的,所以首先要弄清楚我們要操作的跨進程的界面上的對象的信息,這些信息我們可以通過很多現成工具來看,我這里選擇android自帶的uiautomatorviewer。先在模擬器上手工打開被測程序,進入拍照的相機界面,并用uiautomatorviewer查看界面元素信息如下圖(3)所示:

      圖(3)

      我們可以看到,我們要點擊的拍照按鈕的屬性在圖(3)的右下角的列表中已全部展現出來。那么我們該選哪個呢?這個問題取決于adbForAndroid框架支持由哪些屬性來獲取元素。通過查詢其幫助文檔,我們知道目前這個框架中常用的查找元素的方法如下:

      findElementByContentdesc

      findElementByClass

      findElementByText

      findElementById

      由于我現在使用的模擬器版本為4.2.2,所以uiautomatorviewer無法顯示id屬性,如果大家用的是4.3版本以上,就可以看到元素的id屬性了。

      那么現在這種情況來看,我們最好就選擇Contentdesc屬性來定位對象了。代碼很簡單,如下:

      [java] view plain copy Element element =position.findElementByContentdesc("Shutter button");

      adbDevice.tap(element); //點擊拍照按鈕

      好,接下來點擊了拍照按鈕之后,拍照功能還會讓你選擇是確定還是取消操作,如下圖(4)所示:

      圖(4)

      那么如法炮制,我們通過查詢獲知,這個用于確定的“√”按鈕,它的屬性能用于定位的其實只有class屬性。不過這里要注意的是,此時由于我們用的是class屬性,大家可以看到界面上class屬性跟我們要點擊的“√”這個按鈕相同的對象很多,所以我們必須用findElementsByClass方法了。這個方法返回的是一個ArrayList,所以我們可以寫如下的代碼來獲取所有class屬性為”android.widget.ImageView”的元素列表。

      [java] view plain copy ArrayList imageViews =position.findElementsByClass("android.widget.ImageView");

      好,寫完之后,現在問題來了,究竟這個數組里面哪個index才是對應的我們要點擊的“√”按鈕呢?經過試驗,我發現界面上多個相同元素返回到數組中時,對應元素位置是按照界面上的位置從上到下、從左到右來的,所以我們要點擊的這個按鈕的index應該是4。所以點擊它的代碼如下:

      [java] view plain copy adbDevice.tap(imageViews.get(4)); //2是x,3是重拍,4是√

    上面的代碼運行完后,界面就會回到我們的被測程序,后面的操作就不用我再多說了,大家看看是不是非常簡單?

    大笑

      例子2、跨進程操作之打電話

      有了第一個例子的基礎,其實第二個例子就很好實現了。被測程序非常簡單,如下圖(5)所示:

      圖(5)

      點擊“撥打該號碼”后,系統自動進入撥號界面,所以也是典型的跨進程測試場景。

      實現方法還是跟例1中一樣,先還是用uiautomatorviewer查看界面中的對象信息,再使用對應的方法來操作對象即可。而且在這個例子中,我還給大家演示了另外一種情況,即有些跨進程操作不但要進行操作,還要取得一些對象屬性來進行驗證,這也是基本可以的。這里我直接給出我的測試代碼(稍微封裝了一下):

      [java] view plain copy public boolean CallUtil(String callNumber){

      Element element;

      boolean result;

      //驗證是否撥打了正確的號碼

      if(callNumber.length() == 11){//正常號碼需要轉變為 x xxx-xxx-xxxx的格式

      StringformatCallNumber = callNumber.substring(0, 1) + " " +callNumber.substring(1, 4) + "-" + callNumber.substring(4,7) +"-" + callNumber.substring(7, callNumber.length());

      element= position.findElementByText(formatCallNumber);

      try{

      Thread.sleep(2000); //線程休眠2秒

      }catch (InterruptedException e) {

      e.printStackTrace();

      }

      }else{

      element= position.findElementByText(callNumber);//除正常號碼外,其他格式的號碼不進行格式轉換

      }

      if(element != null){

      result= true;

      }else{

      result= false;

      }

      element= position.findElementByContentdesc("End"); //掛斷電話

      if(element != null) adbDevice.tap(element);

      return result;

      }

      好了,整個過程非常簡單。我相信能用robotium的童鞋用起來應該都沒有任何問題,所有代碼都是非常易用易懂的。

      相信通過前面的實例,大家可以發現說這是“史上最簡單”的Robotium跨進程操作解決方案我估計沒人會反對,這并不是夸大事實、博人眼球,確實很簡單,功能也很強大。其他也不用我多說了,最后我再來對該框架總結一下下吧:

      優點:

      1. 確實非常全,基本封裝了adb的所有常用命令,它本身就是一個adb命令使用大全了。

      2. 框架接口設計清晰易懂,簡單明了,封裝成jar包,用起來也很方便。另外希望大家都能看看它的源碼并了解它的實現細節,作者封裝得還是很不錯的,很值得我們學習,而不僅僅是簡單地使用它。

      3. 不需要root權限。其實這點還是很重要的,有些公司的測試機是沒有root權限,用adb就很方便。對于不想放棄robotium,又確實有跨進程操作需求的童鞋來說,真的是非常實用的一個框架。

      目前已知的不足:

      1. 手機的版本必須是4.1以上,即至少必須支持uiautomator的手機才行,因為該框架本身底層是依賴于uiautomator來dump出對象布局xml文件,最終獲取對象的坐標進行操作的,所以你的手機版本本身并不支持uiautomator的話,就沒法實現dump操作。

      2. 有些對象是uiautomator也無法識別和操作的,那當然這個框架也無能為力了。比如屏幕最上方的通知消息欄的對象,所有工具都沒法顯示和識別,這個肯定沒辦法了,另外還比如輸入文字時的彈出鍵盤上的按鈕對象等,也無法識別,大家可以試試。

      以后想要嘗試的改進:

      1. 對于手機版本的支持問題,個人覺得有個曲線救國的方法可以解決。即我們可以稍微修改下源碼,加入判斷手機版本的代碼,判斷當前手機版本如果高于4.1,就直接通過uiautomator來dump,如果低于4.1,則讀取PC上事先導出到指定位置的xml文件。這樣的話,如果你使用的手機不是4.1以上的版本,只需要事先把被測應用用4.1以上版本的手機通過uiautomator先dump到PC的一個指定路徑上就行了,這樣效果應該是一樣的,只要最終能得到對象坐標就OK。

      2. 再加一些比較實用的功能。比如現在可以根據text來查找對象,但實際上很多時候我們可能是得到對象了,但想通過這個對象去獲取對象的其他屬性,所以建議增加類似getXXXXByElement(Element e)這樣的方法,有空試一下,呵呵。

      以上只是我的一些個人想法,如果大家還有一些什么別的建議,也歡迎大家都提出來,一起來完善這個很實用的框架。

      最后,再次感謝AdbForAndroid框架的作者: xuxu。

      框架源碼github地址:https://github.com/gb112211/Adb-For-Test

      本文中相關樣例工程源碼(含被測程序和測試程序)下載

    原文轉自:http://blog.csdn.net/qingchunjun/article/details/42580937

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>