Monday, 1 March 2021

Jacoco shows 0% coverage even though 100% tests are passing

I have been working on an android project in kotlin where I have a few packages: app, package1, package2, package3 each package has its own build.gradle like build.gradle for app, package1, package2, package3 in the respective package. There is also a top-level build.gradle. Now each package has a src and a tests folder. Now I have created a jacoco.gradle file in the package.root. and applied apply from: "$project.rootDir/jacoco.gradle" in each package's build.gradle. Here is my jacoco.gradle file for reference.

apply plugin: 'jacoco'


jacoco {
  toolVersion = "0.8.6"
}

tasks.withType(Test) {
  jacoco.includeNoLocationClasses = true
  jacoco.excludes = ['jdk.internal.*']
}
project.afterEvaluate {

  (android.hasProperty('applicationVariants')
      ? android.'applicationVariants'
      : android.'libraryVariants').all { variant ->
    def variantName = variant.name
    def unitTestTask = "test${variantName.capitalize()}UnitTest"
    def uiTestCoverageTask = "create${variantName.capitalize()}CoverageReport"

    tasks.create(name: "${unitTestTask}Coverage", type: JacocoReport, dependsOn: [
        "$unitTestTask",
        "$uiTestCoverageTask"
    ]) {
      group = "Reporting"
      description = "Generate Jacoco coverage reports for the ${variantName.capitalize()} build"

      reports {
        html.enabled = true
        xml.enabled = false
        csv.enabled = false
      }

      def fileFilter = [
          // data binding
          'android/databinding/**/*.class',
          '**/android/databinding/*Binding.class',
          '**/android/databinding/*',
          '**/androidx/databinding/*',
          '**/BR.*',
          // android
          '**/R.class',
          '**/R$*.class',
          '**/BuildConfig.*',
          '**/Manifest*.*',
          '**/*Test*.*',
          'android/**/*.*',
          // kotlin
          '**/*MapperImpl*.*',
          '**/*$ViewInjector*.*',
          '**/*$ViewBinder*.*',
          '**/BuildConfig.*',
          '**/*Component*.*',
          '**/*BR*.*',
          '**/Manifest*.*',
          '**/*$Lambda$*.*',
          '**/*Companion*.*',
          '**/*Module*.*',
          '**/*Dagger*.*',
          '**/*MembersInjector*.*',
          '**/*_MembersInjector.class',
          '**/*_Factory*.*',
          '**/*_Provide*Factory*.*',
          '**/*Extensions*.*',
          // sealed and data classes
          '**/*$Result.*',
          '**/*$Result$*.*'
      ]

      classDirectories.setFrom(files([
          fileTree(dir: "${buildDir}/tmp/kotlin-classes/${variantName}", excludes: fileFilter)
      ]))

      def variantSourceSets = variant.sourceSets.java.srcDirs.collect { it.path }.flatten()
      sourceDirectories.setFrom(project.files(variantSourceSets))


      def uiTestsData = fileTree(dir: "${buildDir}/outputs/code_coverage/${variantName}AndroidTest/connected/", includes: ["**/*.ec"])

      executionData(files([
          "$project.buildDir/jacoco/${unitTestTask}.exec",
          uiTestsData
      ]))
    }
  }
}

Now the problem is when I run the testDebugUnitTestCoverage task even though all tests present in a package pass the results show 0% code coverage and all lines are missed. Can someone help me find a solution?

Update The coverage is reported with app package and package2(without any change in any files) but jacoco still reports 0 coverage for package1 and package3

Edit added gradle file for 1 of the failing package

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply from: "$project.rootDir/jacoco.gradle"

android {
  compileSdkVersion 29
  buildToolsVersion "29.0.2"

  defaultConfig {
    minSdkVersion 19
    targetSdkVersion 29
    versionCode 1
    versionName "1.0"
    multiDexEnabled true
    javaCompileOptions {
      annotationProcessorOptions {
        includeCompileClasspath true
      }
    }
  }

  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }

  kotlinOptions {
    jvmTarget = JavaVersion.VERSION_1_8
  }

  testOptions {
    unitTests {
      includeAndroidResources = true
      all {
   
        forkEvery = 1
        maxParallelForks = Runtime.getRuntime().availableProcessors()

        testLogging {
          events "passed", "skipped", "failed"
          showExceptions = true
          exceptionFormat = "full"
          showCauses = true
          showStackTraces = true
          showStandardStreams = false
        }
      }
    }
  }

  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    debug {
      testCoverageEnabled true
    }
  }
}

dependencies {
  implementation fileTree(dir: 'libs', include: ['*.jar'])
  implementation(
      'androidx.appcompat:appcompat:1.0.2',
      'androidx.exifinterface:exifinterface:1.0.0-rc01',
      'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-alpha03',
      'androidx.work:work-runtime-ktx:2.4.0',
      'com.google.dagger:dagger:2.24',
      'com.google.firebase:firebase-analytics-ktx:17.5.0',
      'com.google.firebase:firebase-crashlytics:17.0.0',
      "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
  )
  testImplementation(
      'android.arch.core:core-testing:1.1.1',
      'androidx.test.espresso:espresso-core:3.2.0',
      'androidx.test.ext:junit:1.1.1',
      'androidx.work:work-testing:2.4.0',
      'com.google.dagger:dagger:2.24',
      'com.google.truth:truth:0.43',
      'junit:junit:4.12',
      "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version",
      'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.2',
      'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.2.2',
      'org.mockito:mockito-core:2.19.0',
      'org.robolectric:robolectric:4.3',
      project(":package2"),
  )
  kapt(
      'com.google.dagger:dagger-compiler:2.24',
  )
  kaptTest(
      'com.google.dagger:dagger-compiler:2.24',
  )

  api project(':package1')
  implementation project(':package4')
  implementation project(':package3')
}
repositories {
  mavenCentral()
}

configurations {
  all*.exclude module: 'protobuf-java'
}


from Jacoco shows 0% coverage even though 100% tests are passing

No comments:

Post a Comment