2016年10月17日 星期一

Testing: 如何利用Android Studio建立Unit/Instrument測試與報告

前言

為了系統穩定,開發人員會需要建立測試來驗證系統的穩定性,而且開發過程中也會進行重構,同時也能利用測試來證明重構的結果。當然,了解如何撰寫測試是重要的課題之一,但是,首先我們需要先知道該如何透過Android Studio執行測試,並且知道如何產生報告,讓我們以後的單元測試之路,提供良好的運行環境。在Android Studio在測試上提供了Unit及Instrument兩種測試,這篇主要是介紹如何建立、執行、測試結果與報告的產出,至於關於測試的撰寫或是細節,則不多著墨。

目前Android Studio 2.2已經為我們建立好上述兩種測試,當我們建立好專案後,同時也會建立這兩種測試,如下圖。


  • Unit Test: 該測試的實現,都是記錄在test的資料夾中,是可以獨立執行在JVM的測試,無需使用模擬器或是實機。
  • Instrument Test: 這類測試需要執行在模擬器及實機上,相關的實現則是記錄在androidTest的資料夾內。

Instrument測試的執行與測試報告

透過Android Studio執行測試非常簡單,你可以使用模擬器或連接實機後,再利用下列方式來執行:
  • 單獨直接執行某個測試檔案:
    • 我們可以androidTest資料夾中,對著你寫好的Instrument測試檔案點選右鍵,選擇Run “XXXXXTest"就可以運行指定的測試,如下圖。
    • 實際執行的結果,可透過Android Studio介面觀察,如下圖。
  • Gradle Projects視窗執行全部測試:
    • 也可透過Gradle Projects的內容,選擇“:app -> verification -> connectedAndroidTest” ,執行測試的指令,但這種執行方式,不如可直接觀察測試結果便利,因為不會直接幫你從測試報告彙整出在Android Studio的介面中,你還需要到”app/build/reports/androidTests/connected/flavors/index.html"觀察實際的測試結果,如下圖。


    • 若專案沒有任何Build Variants,則執行connectedAndroidTest就可以;若有,則可以根據你要執行的環境名稱,選擇對應的connectedAndroidTest指令即可。(以該專案為例,則是connectedBetaEnvConnectedAndroidTest。)
  • Terminal執行全部測試:
    • 該方式與Gradle Projects視窗執行相同,只是透過Terminal執行,同樣也不像Android Studio介面易觀察,還需透過index.html輔助。
    • 指令執行方式使用”gradle connectedAndroidTest”,如下圖。



Unit測試的執行與測試報告

當你建立好專案時,Android Studio同時會為我們在androidTest與test資料夾建好測試範例,運行Unit測試則無需連接模擬器或實機,直接透過下列方式來執行。

  • 單獨直接執行某個測試檔案:
    • 我們可以test資料夾中,,對著你寫好的Unit測試檔案點選右鍵,選擇Run “XXXXXTest"就可以運行指定的測試,如下圖。

    • 實際執行的結果,可透過Android Studio介面觀察,如下圖。


  • Gradle Projects視窗執行全部測試:
    • 也可透過Gradle Projects的內容,選擇“:app -> verification -> test” ,執行測試的指令,但這種執行方式,不如可直接觀察測試結果便利,因為不會直接幫你從測試報告彙整出在Android Studio的介面中,你還需要到”app/build/test-reports/“找尋xml檔案,如下圖。

  • Terminal執行全部測試:
    • 該方式與Gradle Projects視窗執行相同,只是透過Terminal執行,同樣也不像Android Studio介面易觀察,還需透過xml輔助。
    • 指令執行方式使用”gradle test”,如下圖。

    • 若有Build Variants,也可以使用相對應的指令,以該專案為例:
      • gradle testBetaEnvDebugTest | testBetaEnvReleaseTest
      • gradle testDevEnvDebugTest | testDevEnvReleaseTest
      • gradle testProEnvDebugTest | testProEnvReleaseTest

Instrument測試的覆蓋率

測試報告是為了讓我們知道每個測試案例的結果,若想知道測試的在程式中的涵蓋範圍,我們可以透過下列方式,建立Instrument測試的覆蓋率報告。

  • 在Android Studio中,Instrument測試已經預設使用Jacoco的覆蓋率,所以在該測試下產生覆蓋率相當簡單,只要在Gradle設定“testCoverageEnabled true”即可,如下圖。
  • 加完之後,同樣執行Instrument測試的指令,就可以產生覆蓋率報告了,如下圖。
    • 指令:”gradle connectedAndroidTest”

  • 相對應的覆蓋率文件會建立在“app\build\reports\coverage\connected”路徑下,如下圖。


Unit測試的覆蓋率

Unit測試就比較麻煩一些,不像Instrument測試已經預設好Jacoco,所以我們需要在build.gradle檔案新增產生Unit測試覆蓋率文件的Task。
  • 新增一個名為build_test_report_task.gradle的文件,如下圖。

  • 新增下列程式碼,並把該檔案參照到build.gradle,準備就緒後,Sync Gradle就可以了,如下圖。

    • 當中的dependsOn,指的是參考你所要下的指令,這個範例是只想執行BetaEnv的Unit測試,所以就使用testBetaEnvDebugUnitTest,若你想更換也可以。
    • jacocoTestReport(),指的是你屆時使用上述指令運行測試,要產生Unit測試覆蓋率文件時,後面所要帶的指令,當然你可以更換你所需要的名字。
  • 上述完成後,則可執行你要產生文件的指令,如下圖。
    • 指令:”gradle testBetaEnvDebugUnitTest jacocoTestReport”

  • 相對應的覆蓋率文件會建立在“app\build\reports\jacoco\testReport\”路徑下,如下圖。

Sample Code: https://github.com/xavier0507/Build-Variants-Sample