Android自動化測試探索(五)代碼覆蓋率統計
- 2019 年 10 月 3 日
- 筆記
Android 代碼覆蓋率統計
本周開始準備統計Android自動化用例的代碼覆蓋率,將最終使用的方法記錄下來。
覆蓋率監測的原理
覆蓋率監測的原理跟iOS上的原理差不多,大致的思路參考下吧,
iOS自動化探索(十)代碼覆蓋率統計
Android使用的是JaCoCO覆蓋率統計工具 jacoco 原理篇
必要知識儲備或條件:
- 項目源碼
- Android Studio開發環境
- 基本了解Android項目結構
- 基礎adb操作
同樣如果以上說的幾個都不懂也行, 讓開發幫忙做這些然後編個代碼覆蓋率統計的包給你測試, 測完把手機給開發取數據生成報告。 注意每次測試完先返回手機桌面把程序退到後台等幾秒讓app自己生成日誌文件
下面開始講步驟
步驟1:拉取項目代碼
git clone XXXXXXXXXXX
步驟2:使用Android Studio打開項目
步驟3:配置build.gradle
apply plugin: 'com.android.application' apply plugin: 'jacoco' //加載代碼覆蓋庫jacoco jacoco { toolVersion = "0.7.9" //代碼覆蓋庫jacoco版本號 } android { compileSdkVersion 25 buildToolsVersion "25.0.3" defaultConfig { applicationId "com.whh.initmvp" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { testCoverageEnabled = true //實現代碼覆蓋率 minifyEnabled false //獲取代碼覆蓋率需要設為false (**如果混餚文件配置完畢,設為true也可**) proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { testCoverageEnabled = true //實現代碼覆蓋率 minifyEnabled false //獲取代碼覆蓋率需要設為false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' //.....(此處忽略若干依賴庫) //代碼覆蓋率jacoco(可不引入) // compile 'org.jacoco:org.jacoco.core:0.7.9' } //代碼覆蓋率相關配置 start def coverageSourceDirs = [ '../app/src/main/java' ] task jacocoTestReport(type: JacocoReport) { group = "Reporting" description = "Generate Jacoco coverage reports after running tests." reports { xml.enabled = true html.enabled = true } classDirectories = fileTree( //檢測覆蓋率的class所在目錄(以項目class所在目錄為準) dir: './build/intermediates/classes/debug', //gradle2.3 class所在目錄 //gradle3.2 class所在目錄 dir: './build/intermediates/javac/debug/compileDebugJavaWithJavac/classes', //增加以上目錄中不需要檢測的文件列表 excludes: ['**/R*.class', '**/*$InjectAdapter.class', '**/*$ModuleAdapter.class', '**/*$ViewInjector*.class' ] ) sourceDirectories = files(coverageSourceDirs) //設置需要檢測覆蓋率的目錄 executionData = files("$buildDir/outputs/code-coverage/connected/code_coverage.ec") //存儲APP運行時產生報告的路徑 } //代碼覆蓋率相關配置 end
注意事項:
- compile ‘org.jacoco:org.jacoco.core:0.7.9’ 庫包可不添加依賴;
- classDirectories的設置應以項目編譯後生成的class文件目錄為準,比如:gradle2.3 class所在目錄:dir: ‘./build/intermediates/classes/debug’, gradle3.2 class所在目錄: dir: ‘./build/intermediates/javac/debug/compileDebugJavaWithJavac/classes’
- executionData的設置,自定義生成的報告的路徑及報告名稱,既然設定,在指定目錄下需要有這樣的文件,文件夾及文件名稱都要一一對應,不可粗心輸錯;
- 注意以上注釋的位置,每一個配置務必加上以保證檢測代碼覆蓋率的實現;
步驟4:確認APP有開啟文件讀寫權限
在AndroidManifest.xml中添加
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
步驟5:在項目的BaseActivity Class中添加以下代碼:
這裡不一定都叫BaseActivity文件, 具體要找到自己項目的底層Activity在裏面添加
//生成報告的所在SDcard目錄 public static String DEFAULT_COVERAGE_FILE_PATH = Environment.getExternalStorageDirectory()+"/"; private static final String TAG = "MainActivity"; @Override protected void onStop() { generateCoverageFile(); super.onStop(); } /** * 生成executionData */ public void generateCoverageFile() { OutputStream out = null; try { out = new FileOutputStream(DEFAULT_COVERAGE_FILE_PATH + "/code_coverage.ec", false); //在SDcard根目錄下生產檢測報告,文件名自定義 Object agent = Class.forName("org.jacoco.agent.rt.RT").getMethod("getAgent").invoke(null); // 這裡之下就統計不到了 out.write((byte[]) agent.getClass().getMethod("getExecutionData", boolean.class).invoke(agent, false)); Log.i("whh", "GenerateCoverageFile success"); } catch (Exception e) { Log.i("whh", "GenerateCoverageFile Exception:" + e.toString()); } finally { if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }
步驟6:同步Gradle
點擊Sync Now, 完成後找到Gradle窗口
步驟7:安裝APP到手機
連接上手機後, 點擊上面的installDebug. (注意: 這裡不同的項目可能install目錄下的名稱不一樣, 選擇自己需要的安裝腳本)
步驟8:運行自動化測試用例或手工用例
注意沒運行完一個case需要把手機返回桌面等幾秒,不要殺掉APP進程
並在手機文件根目錄下找到code_coverage.ec文件, 這個就是覆蓋率數據
如果沒有的話重新打開一次APP試試, 還是沒有的話檢查下上面的步驟是不是哪裡漏掉了
步驟9:獲取覆蓋率數據
adb pull /sdcard/code_coverage.ec
步驟10: 拷貝覆蓋率數據
把上面獲取到的覆蓋率數據複製到項目的app/build/outputs/code-coverage/connected/目錄下,如果沒有該目錄,可手動創建
注意這裡的路徑要跟上面build.gradle裏面寫的一致
executionData = files("$buildDir/outputs/code-coverage/connected/code_coverage.ec")
步驟11:生成覆蓋率報告
點擊Gradle窗口中的jacocoTestReport即可
報告一般在appbuildreports目錄
打開裏面的index.html就是我們要的報告了