Jacoco code coverage for android application using

2019-02-15 21:08发布

问题:

My android application uses the following config:

  • Gradle - 0.12.+

Contents of build.gradle file

buildscript {
repositories {
    mavenCentral()
}

dependencies {
    classpath 'com.android.tools.build:gradle:0.12.+'
}
}

repositories {
mavenLocal()
mavenCentral()
}

apply plugin: 'com.android.library'
apply plugin: "jacoco"



dependencies {

compile 'commons-collections:commons-collections:3.2.1'
compile 'org.slf4j:slf4j-android:1.6.1-RC1'

// dependency injection
compile('org.roboguice:roboguice:2.0') {
    exclude module: 'cglib'
    exclude module: 'aopalliance'
    exclude module: 'guice'
}

compile files('libs/guice-3.0-no_aop.jar')
compile 'javax.inject:javax.inject:1'



/*
 * Test dependencies.
 */
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0'

}

android {
buildToolsVersion "20.0"
compileSdkVersion 19

buildTypes {
    debug {
        runProguard false
        testCoverageEnabled true
    }
}

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

defaultConfig {
    minSdkVersion 8
    targetSdkVersion 19
    versionCode 100
    versionName "1.0.0"
}

/*
 * Workaround for packaging bug in Android Gradle plugin regarding duplicate files.
 */
packagingOptions {
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
    exclude 'LICENSE.txt'
}
}

All my tests run successfully when property testCoverageEnabled is set to false. On setting it to true, the following exception is thrown when running the tests

Caused by: java.lang.VerifyError: *** Some class ***
at dalvik.system.DexFile.defineClass(Native Method)
at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:211)
at dalvik.system.DexPathList.findClass(DexPathList.java:313)
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:51)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)

The error happens on the line when mocks are initialised within the tests.

Has anyone managed to generate code coverage metrics for android application which uses mockito library for testing?

回答1:

The following link was very useful in explaining the problem I encountered: http://www.androidpuzzles.com/168_17620080/

I subsequently switched the source and target compatibility settings to Java 1.5 and I was able to run the unit and UI tests (which used both mockito and espresso) and generate code coverage report using Jacoco.

If I had to retain Java 1.7 settings, the workaround would have been to change the scope of private methods in the class being tested to either protected or public scope. This would have then allowed me to generate the code coverage report (overcoming the issue as identified in the link included).



回答2:

Jacoco coverage support has been added to the gradle plugin since 0.10.0. See http://tools.android.com/tech-docs/new-build-system.

Not quite sure I understand why you have such a complex gradle file.



回答3:

You need to compile against Java 1.5 version.

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_5
    targetCompatibility JavaVersion.VERSION_1_5
}


回答4:

https://code.google.com/p/android/issues/detail?id=69174

This issue has been fixed in build tools version 21+

android {
buildToolsVersion "21.1.2"
compileSdkVersion 19

...
}

Upgrade build tools to 21+ to retain Java 1.7 compatibility.