Android自動化測試探索(五)代碼覆蓋率統計


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即可

報告一般在app\build\reports目錄

 

打開里面的index.html就是我們要的報告了

 

 

我的博客即將同步至騰訊雲+社區,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=2crdqmdtflogs


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM