JaCoCo doesn't work with Robolectric tests

前端 未结 5 535
Happy的楠姐
Happy的楠姐 2021-01-01 12:38

I wanted to generate code coverage reports on my JUnit tests in my android project so I added the JaCoCo gradle plugin. This is my project level build.gradle fi

相关标签:
5条回答
  • 2021-01-01 12:54

    I was facing the same issue but now it is resolved for me by following this link,

    issue link: https://github.com/robolectric/robolectric/issues/2230

    Solution for this problem is mentioned here:

    https://github.com/dampcake/Robolectric-JaCoCo-Sample/commit/f9884b96ba5e456cddb3d4d2df277065bb26f1d3

    0 讨论(0)
  • 2021-01-01 12:56

    It is known issue with the possible workaround - https://github.com/jacoco/jacoco/pull/288

    Or downgrade jacoco version to 0.7.1.201405082137

    UPDATE

    The workaround is not needed anymore. You must use gradle version 2.13 and jacoco version 0.7.6.201602180812.

    Update root build.gradle:

    buildscript {
        dependencies {
            classpath 'org.jacoco:org.jacoco.core:0.7.6.201602180812'
        }
    }
    
    task wrapper( type: Wrapper ) {
      gradleVersion = '2.13'
    }
    

    Run ./gradlew wrapper

    Update project build.gradle:

    apply plugin: 'jacoco'
    
    android {
      testOptions {
        unitTests.all {
          jacoco {
            includeNoLocationClasses = true
          }
        }
      }
    }
    
    0 讨论(0)
  • 2021-01-01 13:05

    I had the same issue. I changed the jacoco plugin version and added includenolocationclasses property. Here is the working jacoco.gradle file (I am using gradle wrapper 2.14.1):

    apply plugin: 'jacoco'
    
    jacoco {
        toolVersion = "0.7.6.201602180812"
    }
    
    android {
        testOptions {
            unitTests.all {
                jacoco {
                    includeNoLocationClasses = true
                }
            }
        }
    }
    
    project.afterEvaluate {
        // Grab all build types and product flavors
        def buildTypes = android.buildTypes.collect { type -> type.name }
        def productFlavors = android.productFlavors.collect { flavor -> flavor.name }
        println(buildTypes)
        println(productFlavors)
        // When no product flavors defined, use empty
        if (!productFlavors) productFlavors.add('')
    
        productFlavors.each { productFlavorName ->
            buildTypes.each { buildTypeName ->
                def sourceName, sourcePath
                if (!productFlavorName) {
                    sourceName = sourcePath = "${buildTypeName}"
                } else {
                    sourceName = "${productFlavorName}${buildTypeName.capitalize()}"
                    sourcePath = "${productFlavorName}/${buildTypeName}"
                }
                def testTaskName = "test${sourceName.capitalize()}UnitTest"
                println("SourceName:${sourceName}")
                println("SourcePath:${sourcePath}")
                println("testTaskName:${testTaskName}")
                // Create coverage task of form 'testFlavorTypeCoverage' depending on 'testFlavorTypeUnitTest'
                task "${testTaskName}Coverage" (type:JacocoReport, dependsOn: "$testTaskName") {
                    group = "Reporting"
                    description = "Generate Jacoco coverage reports on the ${sourceName.capitalize()} build."
    
                    classDirectories = fileTree(
                            dir: "${project.buildDir}/intermediates/classes/${sourcePath}",
                            excludes: ['**/R.class',
                                       '**/R$*.class',
                                       '**/*$ViewInjector*.*',
                                       '**/*$ViewBinder*.*',
                                       '**/BuildConfig.*',
                                       '**/Manifest*.*']
                    )
    
                    def coverageSourceDirs = [
                            "src/main/java",
                            "src/$productFlavorName/java",
                            "src/$buildTypeName/java"
                    ]
                    additionalSourceDirs = files(coverageSourceDirs)
                    sourceDirectories = files(coverageSourceDirs)
                    executionData = files("${project.buildDir}/jacoco/${testTaskName}.exec")
                    println("${project.buildDir}/jacoco/${testTaskName}.exec")
                    reports {
                        xml.enabled = true
                        html.enabled = true
                    }
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-01 13:06

    The accepted answer is a bit dated. Here is a similar fix we just implemented. In the module (i.e. app) build.gradle add:

    apply plugin: 'jacoco'
    
    tasks.withType(Test) {
        jacoco.includeNoLocationClasses = true
    }
    

    This does require JaCoCo 7.6+, but you are likely using it already.

    Notes for Studio:

    1. This only fixes the CLI. If you run coverage from Studio using JaCoCo, the Robolectric coverage is still not reported. The default IntelliJ Coverage Runner seems to work fine.
    2. The test were crashing intermittently in Studio unless I added -noverify to the Android JUnit -> VM Options
    0 讨论(0)
  • 2021-01-01 13:17

    change coverage runner to jacoco in android studio 1- select app(root of the project) 2 click on menu (run --> Edit configurations --> code coverage --> choose JaCoCo).

    0 讨论(0)
提交回复
热议问题