2016/11/28

設定 build.gradle 來用 Spock 對 Android 元件進行測試

在「使用 Android Studio 開發 Web 程式 - 測試」中說明了為什麼要選擇 Spock Framework 來做為測試時的 Framework。在實作時 build.gradle 要做一定程度上的設定,才能夠使以 Spock 寫出來的程式碼得以運作,以下將會說明相關設定上的細節。

首先,Spock 的測試程式碼需要使用 Groovy 語言來撰寫,所以 build.gradle 中要先引用 Groovy 的 Gradle Plugin。第一步要在 Root 的 build.gradle 中增加以下內容:
第二步是在要使用 Groovy 的專案 build.gradle 中增加 apply plugin: 'groovyx.android’ 的內容,讓 Gradle 可以正確地識別 Groovy 所寫的程式。

第三步要設定在封裝 Apk 的過程中被排除的檔案:
完成以上的工作就可以設定 Dependencies 以便在撰寫程式時可以引用到 Spock Framework 裡的 Class。但是光只有 Spock 也只能對一般的 Class 進行測試,如果要測試 Android 元件,牽涉到 Context 的問題,還是要使用官方的 Espresso 或是 Robolectric

Espresso 的問題不大,只要把 Java 的寫法改成 Groovy 套到 Spock 的 Class 結構裡就行了。Robolectric 則是要改為引用另一個套件:Robospock,依照 RoboSpock 的官方文件的說明,就可以順利的使用 Spock 來測試 Android 的元件。RoboSpock 就已經有引用 Robolectric 所以自己的 build.gradle 並不需要再設定一次。只是必須受限於 RoboSpock 建置時所設定的 Robolectric 版本,不一定能使用最新版的 Robolectric。

最後一個要注意的事項是,Espresso 在執行前是要經過實際封裝 Apk 的過程,所以 Groovy 在引用時要使用特別為 Android 開發的版本 - org.codehaus.groovy:groovy:2.4.7:grooid,否則很容易會出現超出 64K 的問題。

以下是完整的 build.gradle 的示範內容:
撰寫 Spock 測試前要先手動在 androidTest 或是 test 目錄下增加 groovy 的目錄,其下再依據所屬的 Package 產生路徑結構。

最後,由於相容性的關係,在編譯的過程中會持續出現以下的訊息,但實際操作時並沒有阻擋或影響到測試程式的執行,所以可以忽略、不用理會。
:module:transformClassesWithDexForDebugAndroidTest
AGPBI: {"kind":"error","text":"warning: Ignoring InnerClasses attribute for an anonymous inner class","sources":[{}]}
AGPBI: {"kind":"error","text":"(groovyjarjarantlr.TokenStreamRewriteEngine$1) that doesn\u0027t come with an","sources":[{}]}
AGPBI: {"kind":"error","text":"associated EnclosingMethod attribute. This class was probably produced by a","sources":[{}]}
AGPBI: {"kind":"error","text":"compiler that did not target the modern .class file format. The recommended","sources":[{}]}
AGPBI: {"kind":"error","text":"solution is to recompile the class from source, using an up-to-date compiler","sources":[{}]}
AGPBI: {"kind":"error","text":"and without specifying any \"-target\" type options. The consequence of ignoring","sources":[{}]}
AGPBI: {"kind":"error","text":"this warning is that reflective operations on this class will incorrectly","sources":[{}]}
AGPBI: {"kind":"error","text":"indicate that it is *not* an inner class.","sources":[{}]}
AGPBI: {"kind":"error","text":"warning: Ignoring InnerClasses attribute for an anonymous inner class","sources":[{}]}
AGPBI: {"kind":"error","text":"(groovyjarjarantlr.build.ANTLR$1) that doesn\u0027t come with an","sources":[{}]}
AGPBI: {"kind":"error","text":"associated EnclosingMethod attribute. This class was probably produced by a","sources":[{}]}
AGPBI: {"kind":"error","text":"compiler that did not target the modern .class file format. The recommended","sources":[{}]}
AGPBI: {"kind":"error","text":"solution is to recompile the class from source, using an up-to-date compiler","sources":[{}]}
AGPBI: {"kind":"error","text":"and without specifying any \"-target\" type options. The consequence of ignoring","sources":[{}]}
AGPBI: {"kind":"error","text":"this warning is that reflective operations on this class will incorrectly","sources":[{}]}
AGPBI: {"kind":"error","text":"indicate that it is *not* an inner class.","sources":[{}]}
AGPBI: {"kind":"error","text":"warning: Ignoring InnerClasses attribute for an anonymous inner class","sources":[{}]}
AGPBI: {"kind":"error","text":"(groovyjarjarantlr.debug.misc.ASTFrame$1) that doesn\u0027t come with an","sources":[{}]}
AGPBI: {"kind":"error","text":"associated EnclosingMethod attribute. This class was probably produced by a","sources":[{}]}
AGPBI: {"kind":"error","text":"compiler that did not target the modern .class file format. The recommended","sources":[{}]}
AGPBI: {"kind":"error","text":"solution is to recompile the class from source, using an up-to-date compiler","sources":[{}]}
AGPBI: {"kind":"error","text":"and without specifying any \"-target\" type options. The consequence of ignoring","sources":[{}]}
AGPBI: {"kind":"error","text":"this warning is that reflective operations on this class will incorrectly","sources":[{}]}
AGPBI: {"kind":"error","text":"indicate that it is *not* an inner class.","sources":[{}]}






0 意見:

張貼留言