單元測試框架找尋及搭建任務總結

 1、框架選型

在整個自動化測試架構中,單元測試爲最基礎也是效率最高的層次,如圖1所示,單元是整個軟件的構成基礎,像硬件系統中的零部件同樣,只有保證零部件的質量,這個設備的質量纔有基礎,單元的質量也是整個軟件質量的基礎。java

                                                                                                                

1自動化測試架構及效率算法


在肯定單元測試框架設計前,先作了單元測試技術的調研,對目前市面上開源的工具作了比較分析。數據庫

2和圖3爲兩個備選技術框架,選擇圖2的框架選型1做爲單元測試框架安全

選型1選擇了RoboletricJunitMockito框架,緣由爲Roboletric是以Java Junit的方式運行,脫離了對Android環境的依賴,能夠直接將caseJVM中運行,而Mockito用於在測試過程當中,對於某些不容易構造(如 HttpServletRequest 必須在Servlet 容器中才能構造出來)或者不容易獲取的比較複雜的對象(如 JDBC 中的ResultSet 對象),用一個虛擬的對象(Mock 對象)來建立以便測試的測試方法。服務器

Mock最大的功能是將單元測試的耦合分解開,若是你的代碼對另外一個類或者接口有依賴,它可以模擬這些依賴,並驗證所調用的依賴的行爲。圖4描述了某代碼模塊依賴關係,圖5爲使用Mock解耦後的代碼模塊依賴關係。網絡

                                                                                                                                                          

                                                                                                               圖2框架選型1                                                  3框架選型2架構

                                                                                                                         

                                                                                                 圖4某代碼模塊依賴關係                                                                          圖5 Mock解耦後的代碼模塊依賴關係併發



選型2使用RobotiumAndroid Test Suite(Instrument),該套框架基於Android Runtime,必須在模擬器或真機上測試,效率比較低下,但因爲是Android SDK內置支持的單元測試和功能測試框架,其與系統的聯繫很緊密,測試環境很是接近真實環境,對某些特殊的測試需求,好比須要系統的特定功能屬性或模塊,使用選型2就比較合適。框架

Robotium基於Android Test Suite,提供了更容易使用的測試接口,主要側重黑盒測試。ide

1描述了單元測試技術框架的橫向比較狀況。


1單元測試技術框架比較


優勢

缺點

JUnit

速度快、支持測試覆蓋率等代碼質量檢測工具

沒法作與Android UI相關的操做、與原生Java有差別

Mockito

解除測試對象的依賴關係、驗證行爲等

沒法配置staticfinal等修釋的屬性或方法

Robolectric

支持對Android平臺依賴類底層的引用和模擬(支持有限)

沒法完成UI Layout的測試、啓動速度相對較慢,不利於單獨Unit Test的開發

Robotium

緊密結合產品代碼測試,適合完成Activity粒度的真實場景下的單元測試

依賴安卓平臺、速度很是慢

Android Instrument

可使用絕大多數Android控件和有比較好的設備層支持

速度很是慢、依賴平臺、須要模擬器或真機支持



2、框架移植

主線代碼使用了與圖2框架選型1一致的單元測試框架,只有一點細微的差異,主線單測框架使用PowerMock,本方案採用Mockito,後查明PowerMock包含了Mockito的功能並作了加強,故最終肯定使用PowerMock替換框架選型1Mockito

移植後的編譯環境爲Gradle,須要導入圖6中的單元測試依賴包。

 

6單元測試所需依賴包

3、單元測試框架設計

7描述了單元測試框架,該框架以主線單元測試框架爲基礎,書籤模塊單元測試用例爲模板設計而成。

Robolectric運行環境運行在JVM裏,具備可移植性,JunitMockito運行於Robolectric環境上方,專一於單元測試用例編寫,而Roboletric用於解耦單元測試與Android運行環境的依賴。

7單元測試框架

模塊基礎框架面向特定功能模塊,設計對該功能模塊的特定業務的單元測試架構,不一樣的功能模塊該模塊基礎設計可能不同,對應於不一樣業務的不一樣特性。

模塊單元測試用例是基於模塊基礎框架,編寫具體業務的單元測試用例。



4、單元測試應用

4.1書籤排序

4.1.1用例編寫

根據文檔《XXX書籤雲同步測試用例_20170515.xmind》的順序小節,編寫了14個單測用例。目前測試結果:13個經過測試,1個與預期不符。



8爲單元測試代碼入口,用@Test標記的函數爲一個單元測試方法。

 圖8單元測試代碼入口


9爲某個單元測試用例的代碼示例,使用assertEquals斷言case執行結果的正確性。

9單元測試用例

4.1.2單測效果

10爲單元測試執行結果,從圖中可知共14case1failed13passed.

 圖10單元測試執行結果


11顯示與預期不符的case執行結果。

11與預期不符的case執行結果



4.2書籤數據庫操做

       書籤排序部分的單元測試的目標模塊是獨立於其餘業務模塊和系統平臺的排序算法,實質上是純JUnit單元測試,沒有涉及到RobolectricPowerMock框架,而項目引入單元測試的主要目的是模擬業務場景,並在這些業務場景下運行健壯性、安全性等方面的測試用例,從中發現代碼的問題,進而確保工程質量。

Android項目下作單元測試,必然要基於Android平臺去作單元測試,目前單元測試的框架選定用Robolectric替代Android運行時環境,雖然Robolectric已經較多地應用於Android開發的單元測試,但具體應用到書籤雲同步模塊,該框架是否適用,應用過程會出什麼問題,這些仍須要作風險預妨,表如今實操中就是合理安排任務計劃,預留必定的時間應對可能出現的風險,同時在作單測方案時考慮層面更深、廣度更全面、方案須要作的更詳細和更容易落地等。

4.2.1業務模擬

現階段的業務模擬,主要是模擬本地書籤的增刪改查和雲同步。

12描述了書籤雲同步的類圖,圖中粉色背景部分爲單元測試依賴的類,綠色部分爲華爲去服務SDK中的類。

從圖12中有兩個主要分支,一個爲以BookDaoManager爲首的本地數據庫管理類羣,另外一個爲以HwCloudSyncManager爲首的雲同步類羣。本地書籤的增刪改查是基於BookDaoManager去設計cases,同步測試是基於HwCloudSysncManager去設計cases

12書籤雲同步類圖


        圖13描述了模擬書籤雲同步業務的單元測試架構,JUnit的以@Test標記的Test method爲單元測試入口,在Test method中調用Robolectric的控制對象和影子對象,經過Robolectric去運行App中的UnitTestActivity,測試用例寫在TestActivity,這樣就實現了在JVM上單測Android業務模塊。

13書籤雲同步業務模擬單測架構


值得一提的是,在單元測試架構中,使用者只需關注AndroidInterfaceAndroidInterfaceTest的編寫,無需關注Robolectric容器和具體App結合的原理和邏輯。

113中主要對象含義

對象

子對象

做用

JUnit

Test Method

單元測試入口,用於調用AndroidInterfaceTest中的方法。


AndroidInterface

Android Method

待測方法,運行在Android Runtime中。

AndroidInterfaceTest

Test Method

專測AndroidInterface中的方法。


UnitTestActivity


待測方法運行的容器。


4.2.2用例編寫

根據文檔《XXX書籤雲同步測試用例_20170515.xmind》的穩定性、邊界值等小節,編寫了13個單測用例。目前測試結果:13個經過測試,0個與預期不符。

14~15爲現已實現的用例。

 

                                                                                                                                                       

                                                                                               圖14書籤基本增刪改查用例                                                                                     圖15書籤穩定性用例

 圖16書籤邊界值用例


17展現的是JUnit書籤數據庫操做單測入口。

17書籤數據庫操做單測入口


18爲穩定性測試用例中,書籤批量增刪改的用例代碼。

 圖18書籤批量增刪改用例代碼



19爲書籤雲同步用例模板,全部的書籤雲同步用例均按該模板編寫,圖18中的批量增長、修改和刪除用例就是以該模板(BaseBookmarkDB)編寫而成。

模板(BaseBookmarkDB)分爲五個步驟:

第一步、使用Robolectric構建Activity,並經過ActivityController控制Activity的生命週期到指定狀態;

第二步、執行單元測試;

第三步、打印單元測試相關信息;

第四步、使用Robolectric銷燬Activity,經過ActivityController控制Activity進入銷燬的生命週期序列;

第五步、斷言單元測試結果。

 圖19書籤雲同步用例模板

4.2.3單測效果

20爲書籤增刪改查相關用例的執行結果。

   

20書籤增刪改查用例執行結果


4.3書籤雲同步

書籤雲同步須要調用華爲雲服務SDK將本地書籤數據同步給雲端服務器。用單元測試模擬同步業務,在軟件架構上遇到必定的問題,由於單元測試框架不包含華爲雲服務SDK,將華爲SDK導出而後放到單元測試框架也不必定能正常運行,因此現階段對同步業務的模擬,在設計上採用了一種間接的方式,即經過adb控制手機,將書籤數據經過adb傳送到手機,而後利用am start一個SyncActivity,該SyncActivity負責讀取書籤數據併發起同步請求,最後SyncActivity將同步結果保存到sdcardPC端以輪詢的方式讀取sdcard存儲的同步結果。

21爲書籤雲同步拓撲圖,也是單元測試同步框架實際場景圖,工做人員將A設備經過USB線鏈接到電腦上,工做人員在電腦上運行測試用例。

21書籤雲同步拓撲圖




4.3.1單測框架

22描述了書籤同步單元測試框架的原理。該框架基於C/S架構,Client端運行在電腦上,測試用例跑在Client端,同時要實現一個SyncActivity做爲服務端跑在手機上。

22書籤同步單測框架原理



23爲同步單測框架原理流程圖。

目前同步單測框架已編碼完成,但沒有通過調試驗證執行結果的正確性及框架運行的穩定性。

 圖23同步單測框架原理流程圖


5、改進方案

5.1書籤排序

原有書籤排序採用拓撲排序,時間複雜度爲O(v+e),在排序過程當中各有向邊的權值是時間參數,在和千興的溝經過程中瞭解到,算法並無很好地處理不一樣設備間時間參數的同步,從而有潛在的風險。所以,提出了基於時間同步的改進方案,即統一使用第三方服務器的時間,就可避免因時間參數未同步帶來的風險。

       圖24描述了改進方案的設備時間同步流程。

       圖25描述了改進方案在網絡恢復時的設備時間同步流程。

       圖26描述了書籤雲同步時合併書籤數據流程。


      該方案在雲同步時的排序時間複雜度爲O(m+n),其中m爲本地書籤個數,n爲雲端書籤個數。

      該方案總的排序時間複雜度(書籤雲同步時的排序+同步第三方服務器時間後的排序)O(nlogn)

24設備時間同步流程

25網絡恢復時的設備時間同步流程

26書籤雲同步時合併書籤數據流程


5.2書籤保存策略

在現有實現方案中,用戶增長、修改書籤(包括書籤之間的順序)和刪除書籤後,應用會當即將修改回寫數據庫,在用戶頻繁改寫書籤的場景下,會形成比較大的性能開銷,所以提出一個改進方案,即在用戶進入書籤管理界面後所做的書籤修改,應用只是修改內存中的數據,在用戶退出書籤管理頁面後,應用纔將內存中的書籤數據回寫數據庫,以此避免較多的IO開銷。

在某此極端狀況下,好比應用crash或應用被系統殺掉,致使內存中的書籤數據來不及回寫數據庫,應對這些極端場景,可進一步被充改進方案,在監測到用戶最近一次修改5分鐘後,將內存書籤數據回寫數據庫。


6Gradle工程切Ant預研

6.1 Gradle依賴包導出

添加java library工程,配置好該libraray工程對junitrobolectricpowermock的依賴,如圖6所示,而後在build.gradle中添加一個copyJar taskcopyJar task如圖27所示。

27導出Gradle jartask


運行gradle copyJar,或在圖28中雙擊copyJar,單元測試框架依賴的jar包會保存到build/libs/lib目錄。

28 Gradle projects窗格執行copyJar


6.2 build.xml配置

Ant內置支持JUnit構建,而Robolectric基於JUnit構建,加之PowerMock更傾向於中間件的角色,因此Ant天生支持JUnit + Robolectric + PowerMock組成的Android單元測試框架,準備工做只需將JUnit + Robolectric + PowerMock依賴的jar包放到libs目錄,並在build.xml配置好指向該libsclasspath

29Ant打包apk 有向非循環圖(DAG),粉色背景標識的任務爲單元測試任務,單元測試任務依賴於compile任務,若是要作單運測試,只須要運行ant junit便可。

另外,Ant引入單元測試框架,只需在原打包任務流的基礎上加上junit任務,並使junit任務依賴compile便可,並不會對原打包流程形成大的干擾。

29 Ant打包apk DAG

30和圖31Ant下運行單元測試後生成的結果報告。

30 Ant下單元測試報告

 

 

7、後續工做

調試並驗證同步單元測試框架的正確性,而後增長健壯性、安全性、同步方面的用例編碼實現。

目前的單元測試框架僅應用於書籤雲同步模塊,並處於效果檢驗期,若是單元測試效果較明顯,項目後續還會將單元測試應用於各新增功能模塊的開發和維護。


9、總結

單元測試框架搭建及書籤雲同步順序單元測試用例編寫,是本人第一次進入項目作的事情,先後涉及技術框架選型、主線框架移植、單元測試案例編寫、單元測試案例及測試結果校對等事項,由於暫時沒有代碼權限,目前僅對書籤雲同步的排序進行了單元測試用例編寫及測試,共14個單測用例,其中13個單測用例經過校驗,1個與預期不符,該單測用例緣由目前正在排查。

單元測試是很基礎,也是很重要的開發質量保證模塊,雖然開發人員大多數不肯意寫單元測試,可是從長遠來看,單元測試的做用是至關大的,體如今修改Bug後的代碼校驗、新人接手某功能模塊、模塊修改後的質量保證、最大化地減小軟件功能集成及發佈後的Bug發生機率。

雖然單元測試有不少優勢,但也有缺點,好比單元測試代碼每每是所測目標代碼的2~4倍的體量,通過時間的積累,單元測試代碼的維護是一個問題。

相關文章
相關標籤/搜索