Android集成Jacoco

Jacoco  就是Java Code Coverage的縮寫,也就是 Java代碼覆蓋率。

一、快速集成

在project中加上

 classpath "org.jacoco:org.jacoco.core:0.8.2"

在app的gralde文件第一行下面加上

apply plugin: 'jacoco'

配置jacocoTestReport


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(
            dir: './build/intermediates/classes/debug',
            excludes: ['**/R*.class',
                       '**/*$InjectAdapter.class',
                       '**/*$ModuleAdapter.class',
                       '**/*$ViewInjector*.class'
            ])
    sourceDirectories = files(coverageSourceDirs)
    executionData = files("$buildDir/outputs/code-coverage/connected/coverage.ec")

    doFirst {
        new File("$buildDir/intermediates/classes/").eachFileRecurse { file ->
            if (file.name.contains('$$')) {
                file.renameTo(file.path.replace('$$', '$'))
            }
        }
    }
}

在Application的onCreate加上

createEcFile();
        new Thread() {
            @Override
            public void run() {
                super.run();
                while (true) {
                    writeEcFile();
                    try {
                        Thread.sleep(6000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
private void createEcFile() {
        Log.d(TAG, "create coverage file");
        String DEFAULT_COVERAGE_FILE_PATH = "/mnt/sdcard/" + getPackageName();
        String DEFAULT_COVERAGE_FILE = DEFAULT_COVERAGE_FILE_PATH + "/coverage.ec";
        File file_path = new File(DEFAULT_COVERAGE_FILE_PATH);
        File file = new File(DEFAULT_COVERAGE_FILE);
        Log.d(TAG, "file_path = " + file_path);
        if (!file.exists()) {
            try {
                file_path.mkdirs();
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
private void writeEcFile() {
        Log.d(TAG, "writeEcFile");

        OutputStream out = null;
        try {
            out = new FileOutputStream("/mnt/sdcard/" + getPackageName() + "/coverage.ec", true);
            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));
        } catch (Exception e) {
            Log.d(TAG, e.toString(), e);
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

運行installDebug 

看到安裝成功後,打開App。可以點點App,讓App走走代碼。當然也可以不走,因爲onCreate

執行createDebugCoverageReport

然後,在 /mnt/sdcard/ 加自己包名裏中獲取coverage.ec的文件,放到 app\build\outputs\code-coverage\connected。這裏面可能有一個.ec的文件刪除了就行。

執行jacocoTestReport

然後打開app目錄下的build的reports文件夾下面有jacoco。

用瀏覽器打開

 

因爲配置的地方多我先放一下配置完的樣子

apply plugin: 'com.android.application'
apply plugin: 'jacoco'


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(
            dir: './build/intermediates/classes/debug',
            excludes: ['**/R*.class',
                       '**/*$InjectAdapter.class',
                       '**/*$ModuleAdapter.class',
                       '**/*$ViewInjector*.class'
            ])
    sourceDirectories = files(coverageSourceDirs)
    executionData = files("$buildDir/outputs/code-coverage/connected/coverage.ec")

    doFirst {
        new File("$buildDir/intermediates/classes/").eachFileRecurse { file ->
            if (file.name.contains('$$')) {
                file.renameTo(file.path.replace('$$', '$'))
            }
        }
    }
}


android {
    compileSdkVersion 28
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        debug {
            minifyEnabled false
            testCoverageEnabled = true
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility = 1.7
        targetCompatibility = 1.7
    }
    testOptions {
        unitTests {
            includeAndroidResources = true
        }
    }

    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'com.android.support:appcompat-v7:28.0.0'
        implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'




    }
}

踩坑記錄

1.不需要關閉代碼混淆

 

參考資料:

jacoco仿emma實現統計手工(UI)測試覆蓋率

發佈了34 篇原創文章 · 獲贊 30 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章