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

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

  • <strong id="5koa6"></strong>
  • Android中的單元測試

    發表于:2012-08-30來源:InfoQ作者:張磊點擊數: 標簽:Android
    隨著Agile的普及,以及開發人員對測試重要性的認識逐步加深,單元測試已經成了越來越多軟件項目開發中不可缺少的一部分。無論項目是不是采用TDD的形式來進行開發,單元測試都能夠為項目的修改和重構提供一定的保障。

      隨著Agile的普及,以及開發人員對測試重要性的認識逐步加深,單元測試已經成了越來越多軟件項目開發中不可缺少的一部分。無論項目是不是采用TDD的形式來進行開發,單元測試都能夠為項目的修改和重構提供一定的保障。

      相關廠商內容

      天翼空間借力windows phone 8,幫廣大開發者賺錢!

      MDC2012:9月1日,上海,數十位移動開發專家,與您共敘iOS/Android/WP話題,報名開啟!

      QCon杭州2012:Pragmatic Programmer作者、敏捷宣言創始人之一Dave Thomas

      RightScale創始人、云計算專家Jonathan Siegel確認參加QCon杭州2012

      Amazon五星敏捷圖書作者、敏捷教練Amr Elssamadisy確認參加QCon杭州2012

      相關贊助商

      QCon杭州2012大會10月25~27,現在報名享8折優惠,團購更多折扣!

      Android作為主要的移動平臺之一,吸引了無數的開發人員。但面對Android平臺和環境的種種限制,很多開發人員往往有心無力,很難為其項目添加全面有效的單元測試。

      Android平臺的開發環境中集成了一個測試框架(Instrumented Test),用于支持其單元測試和驗收測試。Robotium同樣提供一個類似于Selenium的測試框架,使得開發人員可以對應用的功能進行驗證。這兩種方式提供的測試環境都類似于集成測試,它們的測試用例都需要運行在模擬器上,通過對模擬器的操作或者mock,來觸發函數調用,進而對其結果進行驗證。這種方法通常粒度較大,測試的編寫和維護較為困難,而最為重要的是,由于測試需要運行于模擬器或測試機器上,我們在運行前需要將測試和應用打包,進行部署安裝,并最終運行在模擬器或測試機器的Delvik虛擬機上,其運行速度較普通的單元測試要慢許多,如果使用TDD來進行開發,根本無法達到快速開發的要求。

      之所以這些框架的測試用例都需要在模擬器中運行,是因為我們平時在開發時所使用的Andorid.jar是被精簡過的,只是用于日常開發的,它只是一個placeholder,使得我們在開發時能夠不出編譯錯誤,它完全是一個stub包,其中所有的類都只是Android平臺接口的一個stub,如果在代碼中運行這個Android.jar,它們所有的方法都只會拋出一個java.lang.RuntimeException(“Stub!”)異常。所以,一旦測試代碼需要真正調用Android平臺相關的類或接口,它們就必須運行于真正實現了Android的環境,如模擬器或者是測試機器。

      我們的另外一個選擇是只對POJO進行單元測試,如果遇到Android相關的代碼,就使用Mock框架對其進行模擬。這種方式一定程度上可以解決我們的問題,但這意味著我們需要大量的在測試環境中使用mock和stub。另外,雖然Android中界面的布局通常使用XML來實現,但項目的代碼中還是會存在各種對界面的操作和更新,UI和邏輯的耦合使測試更加不易。

      而且即使這樣,由于Android平臺的復雜性(static方法,final方法和類,Context和Resources的管理),我們也很難對Android相關的代碼進行測試,以保證測試率。

      那么如何能夠在不增加開發成本的情況下,有一個穩定快速的單元測試環境呢?

      我們目前的選擇是使用MVP模式和Robolectric

      Android的體系結構非常適合于使用MVP模式進行開發,與MVC模式不同,Android中的Activity并不是一個標準的Controller,它的首要職責是加載應用的布局和初始化用戶界面,并接受并處理來自用戶的操作請求,進而作出響應。隨著界面及其邏輯的復雜度不斷提升,Activity類的職責不斷增加,以致變得龐大臃腫。當我們將其中復雜的邏輯處理移至另外的一個類(Presneter)中時,Activity其實就是MVP模式中View,它負責UI元素的初始化,建立UI元素與Presenter的關聯(Listener之類),同時自己也會處理一些簡單的邏輯(復雜的邏輯交由Presenter處理)。如圖所示:

      通過這種職責的分離,一方面代碼的可讀性得到了提高,另一方面我們可以更為方便地通過mock Activity的方式對各種邏輯(Presenter中的方法)進行測試。

      對于測試環境的搭建和測試Android相關的代碼,我們則借助于Robolectric的幫助。

      Robolectric在其所提供的測試框架中,完全模擬了Android SDK的jar文件(不會再有惱人的stub異常),它使得我們的測試可以運行于JVM之上(速度得到大幅度的提升),因此我們可以用它對Android 應用進行測試驅動開發。Roblectric同時實現了Android中對XML的解析,模擬了View,Layout,以及資源的加載,它使得 Android的環境對于開發人員來說更像是一個黑盒,從而使開發人員不用大量使用mock,就可以方便的對資源狀態和Android相關的代碼進行測試。

      Robolectric是如何做到這點的呢?

      Robolectric使用了javassist在運行時動態修改Android.jar中類的byte code,Robolectric會在JVM加載Android.jar包的時候,重寫其中類的方法。Roblectroic會讓這些方法有返回值(null或是0) 而不是拋出異常 ,或者將這些方法調用轉向Shadow Objects來模擬Android SDK的實現。Shadow Objects是Robolectric在運行時插入到Android.jar包相應的類中的,它們會實際處理方法的調用,并記錄相應的狀態,以備在 assert的時候進行查詢。如圖所示。Robolectric提供了大量的Shadow Objects,覆蓋了測試開發過程中絕大多數邏輯功能的需要 。

      Robolectric的使用

      基于Robolectric的測試需要使用其特定的test runner(RobolectricTestRunner)來運行,我們可以通過擴展RobolectricTestRunner來創建一個自己的 test runner,并在其構造函數中設定需要加載的AndroidManifest.xml和resource目錄 。如:

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品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>