【摘要】近幾年移動互聯網行業發展迅猛,帶動智能平臺飛速發展,致使終端智能產品迅速占據當前的消費市場。本文通過對當前Android系統應用開發模式MVP架構的描述,指出該模式下軟件測試的優勢與不足,進而提出MVP架構下提高軟件產品質量的有效測試方法。即使用mockito+powermock測試框架,完成代碼級別的白盒測試方法,來滿足提高軟件質量的產品需求。
【關鍵詞】MVP架構;白盒測試
隨著移動互聯網時代的來臨,智能手機日益走進人們的生活,改變著大家的生活方式。近幾年,智能移動平臺發展尤為迅猛,具有代表性的平臺包括蘋果公司的iOS系統,Google企業的Android系統,加拿大BlackBerry公司的黑莓系統,以及曇花一現的WinPhone系統等等。截止2018年第一季度統計數據,根據最新的凱度移動通信消費者指數(KantarWorldpanelComTech)的智能手機操作系統數據顯示,當前Android系統在智能平臺系統中的用戶占據比重具有絕對地位,高達80%左右,特別是在中國,這個占比率更高達90%。如此龐大的用戶量,致使Android應用軟件數量增長迅速,但由于Android系統從發布之初,就以開源架構為宗旨,完全開放所有代碼及其結構,導致Android系統產品碎片化問題嚴重,并且由于Android系統相較于傳統PC端產品,具有:內存有限,與用戶交互頻繁,系統軟件碎片化,用戶群分散等諸多特點,這些不同都給軟件測試任務帶來前所未有的挑戰,那么如何才能更高效地實施測試,提高產品質量,就成為解決問題的核心。
一、MVP架構介紹
MVP是Model-View-Presenter的首字母縮寫,分別表示模型層-視圖層-發布層,它是MVC架構的一種演變。相較于MVC架構的缺點,MVP架構降低了視圖對模型的依賴與交互,基于MVP架構開發,使用戶界面與業務邏輯分離,架構更靈活,能有效提高程序開發的效率。Model層負責數據的檢索以及數據持久化等操作;View層負責UI界面的顯示和用戶交互操作;Presenter層作為Model與View之間的橋梁,負責兩者之間的業務邏輯處理。邏輯結構如圖1所示。
MVP模式可以更好地將APP程序代碼分層,進而為單元測試提供更好的實踐結構。
二、移動端單元測試框架比較
單元測試以詳細設計說明書和源程序清單為依據,常采用白盒測試用例為主要手段,并組合黑盒測試用例,來尋找模塊內部可能存在的常規錯誤以及邏輯錯誤。單元測試面向的測試對象是代碼,其測試粒度盡可能包含了每一個最小的完整的功能點,并且與邊界、接口等測試手段結合,如此細致的測試粒度,就可以很好地保證測試覆蓋率,更好地提高產品質量。
(一)Junit+Instrumentition測試框架
junit測試框架是一款成熟產品,因為其運行于jvm上,所以其只能測試純Java程序,因此,對于Android程序的單元測試來說,Junit具有其局限性。instrumentation是針對Android系統的JUnit擴展,也就是說對于不涉及Android組件的項目,可直接通過JUnit進行單元測試,而對于調用了Android組件的項目可通過Instrumentation進行單元測試。Instrumentation是Android系統自帶的測試模塊,提供了測試Android四大組件的單元測試接口,但是由于Instrumentation偏底層,封裝性較差,并且需要被測試APP的源碼,這就給測試實現帶來很多代價,因此,直接用Instrumentation而不二次封裝的測試手段已經很少被使用。
(二)Robolectric測試框架
Robolectric測試框架是近幾年流行的一款封裝性較好的單元測試工具。其設計思路是:通過實現Android啟動的相關庫,完成直接運行在JVM上面的Android代碼的設計思想,從而實現盡可能脫離Android運行環境的編譯環境,進而高效地降低Android代碼及測試用例運行速度的設計核心。
Robolecric是TDD模式在Android系統上的具體實現,該框架具有高效的運行速度,并且在測試服務器請求時,對日常的數據模擬和延時發送模擬,給多線程狀態下的測試提供了很好的解決方法。隨著日益豐富的測試需求,該框架的缺點日益突出,其缺點主要集中在無法很好地支持異步測試,需要結合其他的框架來配合完成更多功能。并且受mockito框架的限制,對于final,private,static等類型的mock限制,該框架也具有很大的局限性。
(三)Powermock+mockito測試框架
powermock是一個擴展了其他mock框架的、功能更加強大的框架。Powermockito使用一個自定義類加載類和字節碼操作來模擬靜態方法,構造函數,final類和方法,私有方法,去除靜態初始化器等。通過使用自定義的類加載器,簡化采用的IDE或者持續集成服務器不需要做任何改變,并且該框架很容易使用。Powermock的設計宗旨是:用少量的方法和注解擴展現有的API來實現額外的功能。
簡單實現原理如下:
(1)當某個測試方法被注解@PrepareForTest標注以后,在運行測試用例時,會創建一個新的loader實例,然后加載該測試用例使用到的類(系統類除外)。
(2)PM會根據mock需求,去修改寫在注解@PrepareForTest里面的class文件(當前測試類會自動加入注解中),以滿足特殊的mock需求。
(3)如果需要mock的是系統類的final方法和靜態方法,PM不會直接修改系統類的class文件,而是修改調用系統類的class文件,以滿足mock需求。
三、測試方法實踐
使用MVP架構創建Android應用程序的基本步驟包括:
View:是顯示數據(Model)并且將用戶指令(events)傳送到Presenter以便作用于那些數據的一個接口。View通常含有Presenter的引用。在Android開發中通常將Activity或者Fragment作為View層。
Model:對于Model層也是數據層。它區別與MVC架構中的Model,在這里不僅僅只是數據模型。在MVP架構中Model負責對數據的存取操作,例如對數據庫的讀寫,網絡的數據的請求等。
Presenter:對于Presenter層它是連接View層與Model層的橋梁并對業務邏輯進行處理。在MVP架構中Model與View無法直接進行交互。所以在Presenter層它會從Model層獲取所需要的數據,進行一些適當的處理后交由View層進行顯示。這樣通告Presenter將View與Model進行隔離,使得View和Model之間不存在耦合,同時也將業務邏輯從View中抽離。
從上述相關描述中,可以看出MVP架構存在如下優點及其缺點。
優點:
(1)增強了Activity中代碼的簡潔度,保證了Activity僅僅處理生命周期的任務。
(2)分離視圖邏輯和業務邏輯,分別將其存儲抽象到IView和IPresenter接口中,進而使代碼具有更好的可讀性,并且更容易維護,降低維護成本。
(3)更易于進行單元測試。由于Android系統的Context問題,致使Android的單元測試很難執行,但是采用MVP架構的系統,完美地解決了這個問題,它可以更好地打樁,更加容易mock。
(4)避免Activity的內存泄漏。由于手機系統相較于PC端來說,內存資源非常有限,那么相對來說,APP更容易發生OOM的問題,而其中最常見的問題就是由于Activity泄漏造成的APPcrash的重大bug。那么如果可以很好地避免該bug的發生,就可以更好地增強用戶體驗。采用MVP模式,只要在當前Activity的onDestroy里,分離異步任務對Activity的引用,就能避免ActivityLeak。
缺點:
(1)從MVP的架構的分層結構中可以發現,對視圖的渲染放在了Presenter中,那么會造成視圖與Presenter之間交互頻繁,并且Presenter會隨著視圖的變更而變更。如果Presenter過多地渲染了視圖,勢必會大大增加Presenter與特定視圖間的耦合度。
(2)相較來說,MVP架構會在代碼實現中增加代碼數量,特別是小項目,代碼量增多是一個表面看起來很冗余的問題,但是如果是可復用性非常好的大型項目,MVP架構的優勢是非常明顯的,會給項目的重構,復用,以及代碼安全等各個重要方面帶來非常顯著的優勢。雖然會對架構設計者提出更高的要求,但是,對于實踐中項目的聯調以及產品進度的把握都有很多的益處。
四、代碼片段
(一)實現步驟介紹
(1)創建IPresenter接口,把所有業務邏輯的接口都放在這里,并創建它的實現PresenterCompl(在這里可以方便地查看業務功能,由于接口可以有多重實現所有也方便寫單元測試)。
(2)創建IView接口,把所有的視圖邏輯的接口都放在這里,其實現類是當前的Activity/Fragment。
(3)有圖中可以看出,Activity里包含了一個IPresenter,而PresenterCompl里又包含了一個IView并且依賴了Model。Activity里只保留對IPresenter的調用,其它工作全部留到PresenterCompl中實現。
(4)Model并不是必須有的,但一定會有View和Presenter。
(二)實例分析
五、結語
軟件測試行為是產品高質量的保障行為之一,而高覆蓋率的單元測試方法又是增強產品健壯性的有效技術,只有使用有效的測試手段,才能盡可能地降低產品風險,提高產品質量,減少產品質量問題帶來的代價消耗。
綜上所述,引入MVP模式使得應用程序的整體架構、代碼結構更加清晰,易于理解和組織。由于將業務邏輯與視圖邏輯的代碼拆分,并分別進行單元測試,整體提高了可測試性,并增強代碼健壯性。雖然相比較于MVC模式,MVP架構引入接口帶來了一定的代碼量,但是MVP架構為Android應用程序提供更清晰的層次結構,更加有效地降低視圖與業務之間的耦合度等優點,都是追求高質量代碼的核心需求。
參考文獻
[1]李燦彬,甘宏.基于MVP架構跨平臺的移動應用與開發[J].科技廣場,2017(05):45~48.
[2]王念橋.應用MVP模式改進軟件架構[J].計算機時代,2012(04):37~38,40
[3]劉升貴.基于MVP模式的Android應用程序實現及其單元測試研究[J].福建電腦,2017(07):94~95.
[4]于浩.Android平臺JNI代碼單元測試方法研究[D].成都:西南交通大學,2015.
[5]苑樹慶.基于Android平臺的自動化測試工具的設計與實現[D].沈陽:東北大學,2014.
[6]陳麗萍,張勇,丁智敏.自動化單元測試框架EasyMock分析及其應用[J].巢湖學院學報,2014(06):34~38.
[7]TAMMO,FREESE.EasyMock:DynamicMockObjectsfor Junit[A].Italy,2002:1~5.
[8]JAFADEESHNANDIGAM,TAOYONGLEI.Usingmock objectframeworkstoteachobject-orienteddesign principles[J].2010(01):40~48.
作者簡介:劉萍萍(1982.11—),女,黑龍江哈爾濱人,碩士,研究方向:計算機科學與技術、軟件測試。