【轉】應用寶基於Robotium自動化測試


(轉載:http://tmq.qq.com/2016/05/robotium_for_app_test/)

1 背景目的
應用寶項目組采用FT(Feature Team)模式,整個項目組分為多個FT,而每個FT又同時有多個需求分支在並行運作着,幾乎每天都有多新特性合入主干,項目節奏快、變更頻繁,且又希望能夠短周期內快速地對外發布新版本,做到快速交付、持續交付。
為了支撐項目組的這種研發模式,測試側需要在FT分支上及主干上做大量的測試,而其中在FT分支的rebase測試、合流后驗證、主干灰度測試等等階段還包括大量的重復性測試,因此有必要在這些環節加入自動化測試,以持續驗證新特性未破壞原有系統。

2 框架選擇

如表1所示,對比了目前業界常用的幾個可用於Android端的自動化測試框架:

表1 Android自動化測試框架對比
框架對比
 

通過對比可以發現不同的測試框架各有優缺點,且基本都不能獨自滿足所有的測試場景,正所謂菜刀、牛刀、剪刀、指甲刀,刀刀皆有自己的用途與適用場景,我們需要根據項目情況及實際的使用場景來選擇最適用的工具。Robotium基於原生Android Instrumentation擴展而來,因此基於Robotium的測試既可以使用Robotium本身的API,還可以使用Android原生的豐富API,可擴展性更強,且基於Robotium的測試在執行速度、穩定性上有一定優勢,而應用寶在手機端只有Android版本,也沒有跨平台的需求,綜合考慮,因此選擇了Robotium框架。

3 環境搭建
3.1 基礎環境搭建
測試工程使用了Robotium,采用了的是Android Junit工程,因此需要搭建基礎的Android開發環境,包含JDK、Android SDK、Eclipse + ADT插件 + SVN插件等等開發工具,具體可搜“Android開發環境搭建”搭建基礎環境。
3.2 導入測試工程
1.使用Eclipse導入項目
2.配置Build Path
3.配置keystore
在實際項目中,如果是自家的項目,顯然是不希望對被測App進行重簽名的,有如下原因:
1)每日進行測試的包眾多,一一進行重簽名影響效率
2)如微信、應用寶等應用做了簽名防護措施,重簽名后將導致應用部分功能不可用甚至直接無法啟動
測試工程需要與被測工程簽名一致,因此測試工程需要將keystore配置成應用寶的簽名。Window——Preferences——Android——Build,如圖1所示,點擊Browser,選擇應用寶的debug.keystore簽名,配置完成后,用Eclipse調試時,測試工程打出的apk即是應用寶的簽名了,可以測試應用寶對外發布的任何包。

圖1
圖1 Eclipse中配置自定義簽名

4.配置編碼
新導入工程后,工程可能有許多紅點,此時工程任意有注釋的java文件,如果注釋為亂碼則是因為編碼不一致導致。此時需要將工程編碼設置為utf-8。也可右鍵選擇測試工程,僅設置該工程為UTF-8編碼。
3.3 Eclipse設置
工欲善其事,必先利其器,測試工程使用Eclipse作為IDE,而為了編寫代碼可以更高效,有必要進行一些提高效率的設置。
1.配置輸入聯想
為了提高測試用例的代碼編寫效率,很有必要配置輸入聯想,在Eclipse中Preferences——Java——Editor——Content Assist配置輸入聯想

圖2
圖2 Eclipse中配置代碼自動提示

其中Auto activation triggers for java中默認只有.符號,即輸入.時才會有代碼聯想出來,為了充分利用代碼聯想功能,需要在該輸入框中把abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ這26個字母及.號輸進去,這樣,當鍵入.號或26個字母時,就會有自動提示,提高代碼輸入效率。
2.配置Eclipse的JVM參數
Eclipse的JVM默認設置參數較小,因此可能造成各種卡慢現像,而我們的開發機配置一般較高,可以通過調整JVM參數充分利用機器資源提高Eclipse運行的流暢度,修改Eclipse安裝目錄下的eclipse.ini文件即可,具體可參考如下配置(修改-vmargs參數后面的配置):
-vmargs
-Dosgi.requiredJavaVersion=1.6
-Xms2048M
-Xmx2048M
-Xmn656M
-XX:PermSize=512M
-XX:MaxPermSize=1024M
-XX:+UseParallelGC
-XX:CMSInitiatingOccupancyFraction=85
-Xverify:none
-Xnoclassgc
-XX:+CMSClassUnloadingEnabled
-XX:+CMSPermGenSweepingEnabled
-XX:+DisableExplicitGC
3.關聯源碼
a)關聯內引用jar包的源碼
導入測試工程后,libs下的Robotium和Uiautomator兩個jar使用了properties配置,默認就已關聯上了sources目錄下的源碼,如圖3所示:

圖3
圖3 Eclipse中配置關聯private jar

b)關聯外引用jar包的源碼
關聯外引用jar包的源碼,這里主要關聯Android SDK中的源碼,右鍵android.jar,進入Java Source Attachment選項,關聯sdk中的源碼,如圖4所示:

圖4
圖4 Eclipse中配置關聯外引用的jar

至此,不論進入的是Android SDK還是Robotium中的class類,均可以查看到其源碼實現。
4 Robotium
4.1 Robotium介紹
Robotium對外主要提供以下幾個類:

	By:								//Web元素的選擇器
	Condition:						//接口類,用於等待
	RobotiumUtils:					//工具類
	Solo:							//對外提供各種API
	Solo.Config:					//Solo配置類
	SystemUtils:					//系統級工具類
	TimeOut:						//Solo配置類
	WebElement:						//Web元素的抽象類

其中Solo類是主要對外提供各種API的類,Solo類采用中介者模式,持有com.robotium.solo包下的其它類的的實例對象,當我們調用Solo類中的API時,實則大多數是轉而調用com.robotium.solo包下其它類的方法。com.robotium.solo包下主要有以下類:

	Getter:							//提供控件獲取相關API
	ActivityUtils:					//提供Activity相關API
	Asserter:						//提供斷言相關的API
	Clicker:						//提供模擬點擊相關的API
	ScreenshotTaker:				//提供截圖相關的API
	Scroller:						//提供滾動相關的API
	Searcher:						//提供控件搜索相關的API
	ViewFetcher:					//提供控件過濾相關的API
	Waiter:							//提供控件等待相關的API
	WebUtils:						//提供Web支持相關的API

Robotium為了簡化測試用例的編寫,將以上的這些類都置為了protected,對外只提供Solo類,因此,在編寫測試用例時,主要實例化Solo類即可
Robotium為一款支持黑盒測試也支持白盒測試的自動化測試框架,簡單易用,提供了獲取控件、發送點擊事件、斷言等等API。
主要API如表2所示:

表2 Robotium主要API
Robotium主要API

通過如上API文檔也可以發現,Robotium框架提供的API是有限的,且也只是使用了一小部分Android的API封裝而成。使用Android、Java豐富的類庫我們可以開發出微信、手Q、應用寶等等眾多App,同樣地,我們也可以使用這些豐富的類庫去擴展測試框架。
因此,選擇Robotium測試框架,不只是選擇的一個測試框架,而是選擇的一種測試模式,即基於Android、基於Junit的測試模式。
4.2 Native控件獲取與處理
1.uiautomatorviewer
可以使用%ANDROID_HOME%\tools目錄下的uiautomatorviewer.bat工具直接獲取當前界面的控件結構及其id。
注:uiautomatorviewer只有在Android較高版本(4.3及以上)才能直接獲取控件id值。

圖5
圖5 Uiautomatorviewer查看控件

2.處理唯一id的控件
如果當前界面該控件id是唯一的,則處理起來很簡單,如下:
Button loginBtn = (Button) solo.getView(“loginBtn”);
solo.clickOnView(loginBtn)

3.處理id相同的控件
在Android中,列表ListView采用的是Adapter形式,所以列表中的控件id都是相同的。
此時,需要先獲取節點控件的父視圖,通過父視圖再查找相應的子視圖。

4.控件過濾
測試過程中最常見的方式就是控件過濾
API:getCurrentViews(Class classToFilterBy, View parent)
例如想獲取某一個區域內的所有文本:
ArrayList textViews = holo.getCurrentViews(TextView.class,parentView);
其中parentView為父視圖,獲取parentView下所有的TextView

4.3 WebView控件獲取與處理
WebElement元素獲取可以通過Chrome Mobile Emulation模式獲取。安裝有較新版本Chrome瀏覽器,按F12即可進入Chrome Mobile Emulation模式。
輸入H5頁面鏈接,如:http://xxx.xxx.xxx/index.html

圖6
圖6 Chrome按F12

如圖6所示可以看到’電視劇’擁有class=”classify classify-tv”的唯一屬性。
對於有些無法通過PC瀏覽器打開的H5頁面,可以通過Chrome DevTools連接手機端直接進行調試。
使用DevTools需要以下前置條件:
1.PC端需要安裝Chrome 32及以上版本
2.USB線連接手機設備
3.用於browser debugging:需要Android4.0及以上版本,並安裝有Chrome Android版本
4.用於app debugging:需要Android4.4及以上版本,並將WebView設置為可調試
需要注意的是,PC端中的Chrome版本需要高於手機端中的Chrome版本。
App中將WebView設置為可調試,可使用如下代碼設置:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
DevTools詳情介紹可參見官網:
https://developer.chrome.com/devtools/docs/remote-debugging#reverse-port-forwarding
然后,在Chrome瀏覽器地址欄中輸入“chrome://inspect/#devices”
打開應用寶,進入含有WebView的頁面,例如進入娛樂TAB,如圖7所示,可以看到出現了可以inspect的頁面,點擊’inspect‘按鈕即可對該頁面進行調試,如圖8所示,展示了該頁面的元素。

圖7
圖7 Chrome中使用DevTools
圖8
圖8 DevTools 點擊inspect后展示頁面元素

知道了元素的屬性后,即可調用相應API獲取WebElement對象,通過By方式獲取:getCurrentTxWebElements(By by);By方式支持通過classname、id、textcontent等方式,如:
holo.getCurrentTxWebElements(By.className(className));
獲取到了相應的WebElement對象后,即可對Web元素進行操作:
clickOnWebElement(By by)
clickOnWebElement(WebElement webElement)
waitForTxWebElement(By by,int timeout,boolean scroll)
4.4 斷言
1.Assert中的斷言
使用junit.framework.Assert包中的斷言:斷言條件的true或false、是否為空等等。如圖9所示:

圖9
圖9 Assert中的斷言

2.ViewAsserts中的斷言
使用android.test.ViewAsserts包中的斷言:包括斷言控件是否左對齊、右對齊、父視圖是否包含某子視圖等等。

圖10
圖10 ViewAsserts中的斷言

 

5 跨應用(結合UiAutomator2.0)
2015年3月Android Developers團隊宣布了UiAutomator 2.0版本的發布,這個版本最重要的就是UiAutomator終於可以基於Instrumentation了,使用Instrumentation test runner即可運行UiAutomator,反過來,也即在基於Instrumentation的test中也能使用UiAutomator。因此測試工程可同時使用Robotium和UiAutomator進行更豐富地測試。
新版的UiAutomator隨Android Support Repository發布,可通過SDK Manager下載,以2.1.0版本為例,位於如下所示的路徑中:
%ANDROID_HOME%\extras\android\m2repository\com\android\support\test\uiautomator\uiautomator-v18\2.1.0
新的測試支持庫基本都是基於Android Studio庫,文件以aar結尾而非jar結尾,本小節為方便在Eclipse中介紹需要將aar轉化成jar。如圖11所示,使用壓縮工具打開uiautomator-v18-2.1.0.aar文件,里面的classes.jar文件即是可用於Eclipse的UiAutomator jar包。提取出該classes.jar文件並重命名為方便記憶的jar包文件,導入至使用了Robotium的測試工程即可。

圖11
圖11 解壓aar文件

如圖12所示,應用寶在通知欄中開啟了快捷工具欄,測試此功能時需要開啟通知欄,並點擊工具欄中的按鈕,這樣的操作僅通過Robotium框架是無法完成的,此時就可以結合UiAutomator來實現。

圖12
圖12 應用寶快捷工具欄

UiAutomator發布2.0版本后,可以通過傳入Instrumentation對象獲得UiDevice對象。
UiDevice.getInstance(instrumentation);通過UiDevice對象可以完成點擊Home鍵、打開通知欄,並通過UiDevice的findObject方法可以根據文本、資源id等等查找控件,並通過UiObject對象完成點擊操作。
使用的findObject方法得到的為UiObject對象,此外也可以通過By的方式獲取UiAutomator中的UiObject2對象,例如:
uiDevice.findObject(By.res(“com.tencent.android.qqdownloader”, “entry_text_1”)).click();
UiAutomator2.0還有許多更豐富更強大的功能,這里就不再一一介紹,總之,通過與Instrumentation結合可以方便地在測試工程中完成跨應用的操作,進行更豐富地測試。

6 測試工程
6.1 測試工程概覽
使用Robotium進行自動化測試,測試工程為一個Android Junit Test工程,可以依賴被測工程,與可以選擇獨立存在。
關聯被測工程源碼的好處在於可以調用被測工程的代碼,因此可以更容易地獲取到被測應用內部的狀態,例如拿到被測應用ListView內部填充的數據等等。而這樣也會帶來一些弊端:
1.測試工程的自動化編譯打包也需要關聯被測工程,腳本復雜度及維護成本增加
2.如果采用R.id.xxx方式獲取控件的話,被測工程增加、刪除布局文件都可能影響到測試工程的編譯結果
3.如果被測應用進行了代碼混淆,引用被測工程的代碼復雜度將大大提高
鑒於此,應用寶采用的是脫離被測工程的方式,同一份測試apk可以同時測試多個版本的被測應用,另外,即使大家選擇有源碼的方式,也不建議使用R.id.xxx的方式獲取控件。
測試工程需要在AndroidManifest.xml文件中注冊instrumentation用於指定被測應用:

    instrumentation 
        android:targetPackage="com.robotium.android.notepad" 
        android:name="android.test.InstrumentationTestRunner"

在同一個測試工程中我們可以只注冊一個instrumentation,也可以同時注冊多個,例如當被測應用有多個,而測試工程又不想分別建立多個時,則可以使用注冊多個的方法。首先,先編寫一個繼承自android.test.InstrumentationTestRunner的自定義InstrumentationTestRunner,然后同樣地在AndroidManifest.xml中注冊:

instrumentation 
        android:targetPackage="com.robotium.android.anothernotepad" 
        android:name=".instrumentation.InstrumentationTestRunner" 

6.2 測試用例
6.2.1 測試用例生命周期
測試用例基於Android Junit,每個用例遵循以下三個步驟:
1)首先,執行setUp()方法,用於初始化。
2)然后,執行以public且方法名以test開頭的用例方法。
3)最后,執行tearDown()方法,用於釋放資源等
另外,由於許多用例都需要擁有同樣的功能特點,例如需要能夠進行出錯重試與出錯截圖等等,因此,可以編寫一個共有的測試基類,應用寶測試工程中所有的測試類均繼承自SingleLaunchActivityTestCase2這個類。

6.2.2 測試用例編寫
測試用例編寫的質量直接關系到用例的穩定性、維護成本以及是否能發現有效問題等等,因此是自動化測試中的關鍵一環。
首先,是確定測試用例的來源。
當開始准備編寫自動化測試用例時,需要確定測試用例的來源,即需要明確例如以下幾個方面:
 哪些功能是主要功能、哪些功能可以自動化
 用例的優先級、作用的測試階段
 測試一個功能需要哪些驗證點
不同的項目組需要思考的點可能不一樣,但目的是一致的,需要明確測試用例的來源,而不是任意地開始編寫用例。應用寶中采用CheckList的形式,通過與各業務線討論評審的方式確定關鍵功能、是否自動化、用例優先級、測試驗證點等等。
然后,應該合理地去設計自動化測試用例
在設計自動化測試用例時,除了實現用例來源中的功能步驟外,用例的原子性是需要額外注意的,這將影響到多個用例在一起時是否可以高效穩定地運行。用例的原子性,即指用例間應該保持相對獨立,不因用例執行的先后順序而彼此干攏。
此外,應該以工程的視角去看待測試用例
測試代碼也應該以工程的視角去看待,包括配置管理、結構管理、項目化運作等等。在編寫測試用例過程中也應該盡可能地從工程角度在代碼易用性、維護性方面去多加考慮。測試代碼也應該要有代碼規范,包含命名規范、編寫規范、注釋規范等等,以使測試用例能高效有質量地運轉起來。
最后,應該驗證測試用例的有效性
自動化測試用例本身也是需要經過驗證與測試的,一個測試用例本身運行通過了並不一定代表用例就是有效的。例如可能因為檢查點判斷有問題導致該用例始終通過,而一般當用例開始交付運行后,如果一直是通過的,那么往往就不會有人關注,且測試人員會認為該模塊已經有自動化測試去保障從而容易忽略基本的測試,所以常常無效的自動化測試用例比沒有自動化測試更可怕,需要警惕出現無效的測試用例。在編寫測試用例時需要驗證用例的有效性,在測試用例交付使用后,也應該定期地關注測試用例的運行情況及其有效性。

6.2.3 測試用例執行
1. 傳統命令行執行方式

(1)Running all tests:

adb shell am instrument -w com.tencent.assistant.qa/android.test.InstrumentationTestRunner

(2)Running a single testcase:

adb shell am instrument -w -e class com.tencent.assistant.qa.testcase.nuclear.MobileAccelerateTest com.tencent.assistant.qa/android.test.InstrumentationTestRunner

(3)Running a single test:

adb shell am instrument -w -e class com.tencent.assistant.qa.testcase.nuclear.MobileAccelerateTest#testMgr_MobileAccelerate com.tencent.assistant.qa/android.test.InstrumentationTestRunner

(4)Running multiple tests:

adb shell am instrument -w -e class com.tencent.assistant.qa.testcase.pangu.FoundTabActivityTest,com.tencent.assistant.qa.testcase.nuclear.AssistantTabActivityTest com.tencent.assistant.qa/android.test.InstrumentationTestRunner

 

2.使用spoon執行

java -jar spoon-runner-1.1.3-SNAPSHOT-jar-with-dependencies.jar \

–apk example-app.apk \

–test-apk example-tests.apk \

–class-name com.tencent.assistant.qa.testcase.common.SearchTest

robutim1

 

3. 在Eclipse中執行
選擇一個測試類后,右鍵Run As —— Android Junit Test執行即可
注:在Run Configuration中,如設置有多個Instrumentation runner,則需要指定InstrumentationRunner,如圖13所示:

圖13
圖13 配置Run Configuration

6.2.4 測試用例管理
當編寫了較多測試用例時,就需要將測試用例分類管理起來,以方便統一維護及用例分級。基於Junit的測試可以使用TestSuite的方式進行管理。
由於在測試執行時,不同的用例執行時間長短不同,且作用的測試階段也各不相同階,因此在進行用例管理時,需要明確用例的級別,例如區分是核心功能用例還是普通用例,從而將不同級別的用例放於一處進行管理,在執行時才可以有針對性地進行測試。

6.3 測試報告
6.3.1 Spoon報告
Spoon是一個由主導有okhttp、retrofit、leakcanary等眾多優秀開源項目的Square公司在GitHub上的開源項目,志力於改善基於Instrumentation的測試。通過分布式地在多台手機上同時執行基於Instrumentation的測試用例,並且在測試完成后生成統一的擁有測試結果概覽、截圖、運行時日志等等功能的HTML形式測試報告,Spoon可以更加快速有效地對Android終端進行自動化測試。
項目開源地址:https://github.com/square/spoon
測試采用的Spoon生成,生成報告如圖14所示,其中綠條表示用例通過,紅條表示用例失敗:

圖14
圖14 Spoon報告首頁

點擊紅條可跳轉至失敗用例的報告詳情頁,如圖15所示:

圖15
圖15 失敗用例的報告詳情頁

用例采用出錯重試並截圖機制,當用例失敗時進行截圖,並往后開啟截取一系列運行時的圖片,每個用例右邊有四個按鈕,分別為將截圖以gif格式播放、展示多台手機下同一用例運行情況、運行時日志查看、javadoc文檔鏈接。
例如點擊右3按鈕查看運行時日志,如圖16所示:

圖16
圖16 運行時日志

6.3.2 歷史數據聚合報告
Spoon會類似單元測試形式的XML報告文件,因此其他測試平台可以通過解析junit-reports目錄下的XML報告獲取用例執行的詳情數據,對每次的測試進行入庫存儲,積累日常的測試數據,生成歷史記錄的測試報告頁面。

圖17
圖17 歷史數據聚合報告

 

7 持續集成
7.1 Jenkins介紹
Jenkins,原名Hudson,2011年改為現在的名字,它是一個開源的實現持續集成的軟件工具。官方網站:http://jenkins-ci.org/。
Jenkins 能實施監控集成中存在的錯誤,提供詳細的日志文件和提醒功能,還能用圖表的形式形象地展示項目構建的趨勢和穩定性。
7.1.1 參數化構建
Jenkins支持多種參數化構建,如圖18所示:

圖18
圖18 參數化構建

 

7.1.2 構建前
構建前可關聯SVN,設置定時觸發器等等常規操作。
此外,安裝相應插件后,構建前也可以刪除workspace中的指定文件、設置當超時的時候是否停止構建、向workspace事先拷貝文件等等操作

7.1.3 構建
構建可以增加如圖19所示的諸多構建步驟:

圖19
圖19 構建步驟

常用的有Execute shell(在Linux機器中執行時),用於執行shell腳本
Execute Windows batch command(在Windows機器中執行時),用於執行bat批處理腳本

7.1.4 構建后
構建后可以選擇如圖20所示的構建后步驟,常用的有郵件發送、觸發新的構建任務、傳遞參數等等功能。

圖20
圖20 構建后步驟

 

7.2 整體流程圖
由7.1節可知,Jenkins支持參數化構建、關聯SVN、能設定觸發時機、支持執行Shell或bat腳本、支持執行后郵件反饋、支持分布式運行等等一系列持續集成的流程。且Jenkins包含豐富的插件可以用於擴展功能,結合實際項目,因此應用寶使用Jenkins來做自化測試的持續集成,整體流程如圖21所示。
BVT自動化測試根據不同的分支支持定時觸發、分支監控及手動上傳三種方式觸發測試。任務創建后,將根據所選擇的測試節點執行測試,測試用例采用基於Robotium框架編寫,測試執行采用基於Spoon框架執行,因此支持在單台手機上執行也支持同時在多台手機上同時執行。測試執行完成后數據報告將回傳服務端進行數據處理,數據處理完成將在相應平台上展示數據報告並郵件反饋相關負責人。

圖21
圖21 整體流程圖

定時觸發:用於主干每日夜里執行全量用例
分支監控:用於監控DB分支,當DB分支有新的構建時,就拉取相應apk進行BVT測試
手動上傳:支持各FT及發布分支手動上傳apk文件,手動觸發BVT測試
任務創建:任務創建時會將測試工程進行編譯打包生成測試.apk,並會將測試工程中需要用到地腳本文件、jar包插件等統一拷貝至服務端的一個根據job名稱命名的臨時目錄。
執行測試:在執行測試前,會將服務端該臨時目錄下的所有文件push至Slave執行機,然后執行相應的初始化腳本,例如卸載安裝應用、清理手機中的殘留數據等。
數據處理:在執行測試完成后,執行相應腳本,從手機中pull出測試產物,例如代碼覆蓋率用的ec文件、性能監控數據、協議日志數據、內存快照文件等。然后使用相應的jar包插件解析測試報告、上傳數據至數據庫等操作。
郵件反饋:調用郵件模版將測試報告發送指定的收件人。
在這種模式下,BVT測試支持自動執行也支持手動觸發執行,在Jenkins中以模版形式既可較靈活地進行配置,且配置維護也較為容易。另外任意能連接成為Jenkins節點的PC都可以迅速成為節點PC機,在節點PC上掛上手機即可成為系統的一部分,可以執行BVT自動化測試任務。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM