代碼覆蓋率的作用主要是用來查看測試用例執行完畢后,有哪些代碼尚未覆蓋到,未覆蓋到的代碼通常意味着未覆蓋到的功能或場景,對於Andriod程序來說,好像國內聊到這個領域的文章不多,這里記錄下來供大家參考。
因為Andriod程序實際上就是Java程序,這里先不談Andriod native C程序的代碼覆蓋率收集(后面的文章會講到,其實就是用gcov做的),Java程序的代碼覆蓋率統計可以使用一個開源軟件Emma,Emma並不需要源碼就可以統計代碼覆蓋率 。這是因為統計代碼覆蓋率的做法有兩種(參看以前的文章:):
1、修改程序源代碼,添加統計代碼覆蓋率的代碼,例如gcov采用的就是這種做法。
2、修改最終程序,比如Emma就是修改Java class的字節碼Oolong代碼。為了能夠將統計到的代碼覆蓋率結果追溯到源代碼,一般是將Java編譯成調試(Debug)版,做法是:Emma在每個Oolong跳轉代碼前加入統計覆蓋率的代碼,而調試版的class,里面會有.source, .line. .var這些指令,告訴調試器字節碼與Java源代碼、Java變量與Oolong變量的數字引用的映射關系,這種做法的好處是,只要你的程序最終會生成Java字節碼,例如Scala之類的程序,生成的調試版都可以用Emma修改,達到統計代碼覆蓋率的目的。Java虛擬機對調試的支持,請參考書籍《Programming for the Java™ Virtual Machine》第7章里的描述。
因為Andriod程序在部署到設備之前,會有個程序(dx)將Java字節碼翻譯成Andriod虛擬機里的字節碼,所以可以在翻譯之前使用Emma修改class文件,再打包。
實際上Andriod提供了一個ant的 build文件,里面就封裝了這個功能,我這里將這個腳本做的事情挖了出來,解釋一下各步驟。在解釋之前,先看看如何用ant編譯一個覆蓋率統計版:
1、從eclipse的andriod工程里生成一個ant的build文件,andriod-app就是工程名:
android update project -p android-app
2、將eclipse的andriod測試工程也轉換成ant工程,-m選項指定了測試工程對應的主andriod工程的位置,而android-test就是測試工程名:
android update test-project -m ../android-app -p android-test
3、執行下面的命令,編譯、執行單元測試、收集覆蓋率:
ant clean emma debug install test
4、在設備上,/data/data/<package name>/目錄里,有一個files文件夾里有coverage.ec文件,即記錄了代碼覆蓋率信息,但這個信息還需要跟源碼做一次映射才能看到哪些代碼行已覆蓋。
5、將上面coverage.ec文件拷貝到andriod主工程的bin文件夾里,這個文件夾里有一個文件名coverage.em,里面記錄了修改過的字節碼與源代碼的映射關系。
6、要查看代碼覆蓋率時,執行下面的命令(andriod SDK里以及自帶了emma.jar),下面命令里的sp參數即指定了 源代碼的位置:
java -cp ~/android-sdk/tools/lib/emma.jar emma report -r html -in coverage.em -in coverage.ec -sp ~/<andriod-app>/src/
這里我們把ant命令分解(假設已經將andriod eclipse工程轉換成ant工程了),實際上執行下面幾個命令就可以了,下例中~/research/multiplatformdemoproject就是andriod的主工程路徑:
cd ~/research/multiplatformdemoproject/
# 編譯成調試版
ant debug
# 在打包成dex文件之前,修改class字節碼
cd bin
java -cp ~/android-sdk/tools/lib/emma.jar emma instr -ip classes -d instrumented
# 將修改成覆蓋率統計版的class字節碼打包成andriod虛擬機文件
~/android-sdk/platform-tools/dx --dex --debug --no-optimize --output=classes.dex instrumented
~/android-sdk/platform-tools/aapt package -v -f -M /home/shiyimin/research/multiplatformdemoproject/AndroidManifest.xml -S /home/shiyimin/research/multiplatformdemoproject/res -I /home/shiyimin/android-sdk/platforms/android-8/android.jar -F multiplatformdemoproject.unsigned.apk /home/shiyimin/research/multiplatformdemoproject/bin/
# 簽名
jarsigner -keystore ~/.android/debug.keystore -storepass android -keypass android -signedjar multiplatformdemoproject.signed.apk multiplatformdemoproject.unsigned.apk androiddebugkey
~/android-sdk/tools/zipalign 4 multiplatformdemoproject.signed.apk multiplatformdemoproject.apk
# 部署主程序到設備上
~/android-sdk/platform-tools/adb install multiplatformdemoproject.apk
# 編譯測試用例
cd tests
ant debug
# 部署並且執行測試用例
~/android-sdk/platform-tools/adb install multiplatformdemoproject.test-debug.apk
~/android-sdk/platform-tools/adb shell am instrument -w -e coverage true cc.iqa.studio.demo.test/android.test.InstrumentationTestRunner
# 查看代碼覆蓋率結果報告
cd http://www.cnblogs.com/bin/
~/android-sdk/platform-tools/adb pull /data/data/cc.iqa.studio.demo/files/coverage.ec .
java -cp ~/android-sdk/tools/lib/emma.jar emma report -r html -in coverage.em -in coverage.ec -sp ~/research/multiplatformdemoproject/src/
下面是幾個截圖: