简体   繁体   中英

Is it possible for Instrumented tests to create coverage for a library module?

I am in the process of modularising the app I am working on and my coverage has dropped over 20% since splitting my instrumentation tests into the app module.

The app is being split into app , core , custom , where core is an android library and the other 2 modules are apps. The majority of the app's functionality will live in core and it is currently mostly tested through instrumentation tests which now reside in app .

Is there a way that instrumentation tests in an application module can generate a coverage report that will include library module sources?

I looked at this question here which bears great similarity to my dilemma but this seems outdated as publishNonDefault is deprecated and does nothing as libraries now publish all variants

My efforts are ongoing on this PR

It will be difficult to complete modularisation with such a drop of coverage, I would expect the coverage to be unchanged post modularisation.

EDIT: I have created a repro project here

See the JacocoMerge task which can merge multiple jacoco execution files into a single file. You can then generate a JacocoReport from the merged exec file

No.

Just add your instrumentation tests to the module that has the code under test.

Was under a misconception that instrumentation tests could not be run on a library project due to this SO answer , I have proposed an edit to reflect the up to date documentation.

EDIT: I later found a solution but honestly it probably should not be used and this is the path you should go down. Instrumentation tests probably shouldn't be used for coverage to begin with and unless you are stuck with legacy do not use the solution presented on this page.

See the JaCoCo plugin docs which show that a task named "jacocoTestReport" is added by the JaCoCo plugin. And you can see there's an "additionalSourceDirs" property on the JacocoReport task

So you can do something like

apply plugin: 'java-library' 
apply plugin: 'jacoco' 
evaluationDependsOn ':another-project'
tasks.withType(JacocoReport) {
   def otherSourceSet = project(':another-project').sourceSets.main
   additionalSourceDirs.from otherSourceSet.allJava
   additionalClassDirs.from otherSourceSet.output
} 

Eventual answer came from here so all credit to them. Posting the contents of the file here for anybody looking in the future

apply plugin: 'jacoco'

jacoco {
    toolVersion = "$jacocoVersion"
}

tasks.withType(Test) {
    jacoco.includeNoLocationClasses = true
}

task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'createDebugCoverageReport']) {

    group "Reporting"
    description "Generate Jacoco coverage reports."

    reports {
        xml.enabled = true
        html.enabled = true
        html.destination file("${rootProject.buildDir}/coverage-report")
    }

    def javaClasses = []
    def kotlinClasses = []
    def javaSrc = []
    def kotlinSrc = []
    def execution = []

    def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']

    rootProject.subprojects.each { proj ->
        javaClasses   << fileTree(dir: "$proj.buildDir/intermediates/javac/debug", excludes: fileFilter)
        kotlinClasses << fileTree(dir: "$proj.buildDir/tmp/kotlin-classes/debug", excludes: fileFilter)
        javaSrc       << "$proj.projectDir/src/main/java"
        kotlinSrc     << "$proj.projectDir/src/main/kotlin"
        execution     << fileTree(dir: proj.buildDir,
                includes: ['jacoco/testDebugUnitTest.exec',
                           'outputs/code_coverage/debugAndroidTest/connected/**/*.ec'])
    }

    sourceDirectories = files([javaSrc, kotlinSrc])
    classDirectories = files([javaClasses, kotlinClasses])

    print execution

    executionData = files(execution)

    doLast() {
        print "file://${reports.html.destination}/index.html"
    }
}

FileFilter probably needs some improvement for a modern Android application eg Dagger/ViewBinding.

I applied this in my app/build.gradle and after running gradlew jacocoTestReport the report with full coverage was present in [projRoot]/build/coverage-report .

Repro project has been updated with the solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM