diff --git a/README.md b/README.md index f632b52..b293c19 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,17 @@ # Unified Code Coverage for Android -> Fork version with multi module implementation - -> [Multi Module Example](https://github.com/tramalho/unified-code-coverage-android/tree/mixed-languages-multi-module) - -> Please check original version links below. +A sample project showcase of how to merge the coverage data from both `androidTest` and `test`. -============ +## AGP Version -A sample project showcase of how to merge the coverage data from both `androidTest` and `test`. +Currently written with AGP 4.2.0 as there are some issues with AGP 7.0.0 creating coverage unit test coverage files +in conjunction with instrumented test coverage files described here: https://issuetracker.google.com/issues/195860510 [Java Example](https://github.com/rafaeltoledo/unified-code-coverage-android/) [Kotlin Example](https://github.com/rafaeltoledo/unified-code-coverage-android/tree/kotlin-coverage) -[Java+Kotlin Example](https://github.com/rafaeltoledo/unified-code-coverage-android/tree/mixed-languages) +[Java+Kotlin Multi-Module Example](https://github.com/rafaeltoledo/unified-code-coverage-android/tree/mixed-languages) ============= diff --git a/another_module/build.gradle b/another_module/build.gradle index de62feb..5586111 100644 --- a/another_module/build.gradle +++ b/another_module/build.gradle @@ -1,14 +1,13 @@ apply plugin: 'com.android.library' apply plugin: 'org.jetbrains.kotlin.android' - -apply from: rootProject.file("jacoco.gradle") +apply from: "../jacocoDeps.gradle" android { - compileSdkVersion 28 + compileSdkVersion 30 defaultConfig { minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 30 versionCode 1 versionName '1.0' @@ -44,18 +43,24 @@ android { dependencies { - implementation 'androidx.appcompat:appcompat:1.0.2' + implementation "androidx.appcompat:appcompat:$appCompatVersion" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" - androidTestImplementation 'androidx.test:core:1.0.0' - androidTestImplementation 'androidx.test.ext:junit:1.0.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' - androidTestImplementation 'androidx.test:rules:1.1.0' - androidTestImplementation 'androidx.test:runner:1.1.0' - androidTestUtil 'androidx.test:orchestrator:1.1.0' + androidTestImplementation "androidx.test.ext:junit:$testXJunitVersion" + androidTestImplementation "androidx.test.espresso:espresso-core:$espressoCoreVersion" - testImplementation 'junit:junit:4.12' - testImplementation 'org.robolectric:robolectric:4.0.2' + androidTestImplementation "androidx.test:core:$testXVersion" + androidTestImplementation "androidx.test:rules:$testXVersion" + androidTestImplementation "androidx.test:runner:$testXVersion" + androidTestUtil "androidx.test:orchestrator:$testXVersion" + testImplementation "junit:junit:$junitVersion" + testImplementation "org.robolectric:robolectric:$robolectricVersion" + // Needed for https://github.com/robolectric/robolectric/issues/5921 + testImplementation ('org.bouncycastle:bcprov-jdk15on') { + version { + strictly '1.65' + } + } } diff --git a/app/build.gradle b/app/build.gradle index c9564b0..2e438e2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,14 +1,14 @@ apply plugin: 'com.android.application' apply plugin: 'org.jetbrains.kotlin.android' -apply from: rootProject.file("jacoco.gradle") +apply from: "../jacocoDeps.gradle" android { - compileSdkVersion 28 + compileSdkVersion 30 defaultConfig { applicationId 'net.rafaeltoledo.coverage' minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 30 versionCode 1 versionName '1.0' @@ -45,18 +45,25 @@ dependencies { implementation project(path: ':another_module') - implementation 'androidx.appcompat:appcompat:1.0.2' + implementation "androidx.appcompat:appcompat:$appCompatVersion" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" - androidTestImplementation 'androidx.test:core:1.0.0' - androidTestImplementation 'androidx.test.ext:junit:1.0.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' - androidTestImplementation 'androidx.test:rules:1.1.0' - androidTestImplementation 'androidx.test:runner:1.1.0' - androidTestUtil 'androidx.test:orchestrator:1.1.0' + androidTestImplementation "androidx.test.ext:junit:$testXJunitVersion" + androidTestImplementation "androidx.test.espresso:espresso-core:$espressoCoreVersion" - testImplementation 'junit:junit:4.12' - testImplementation 'org.robolectric:robolectric:4.0.2' + androidTestImplementation "androidx.test:core:$testXVersion" + androidTestImplementation "androidx.test:rules:$testXVersion" + androidTestImplementation "androidx.test:runner:$testXVersion" + androidTestUtil "androidx.test:orchestrator:$testXVersion" + + testImplementation "junit:junit:$junitVersion" + testImplementation "org.robolectric:robolectric:$robolectricVersion" + // Needed for https://github.com/robolectric/robolectric/issues/5921 + testImplementation ('org.bouncycastle:bcprov-jdk15on') { + version { + strictly '1.65' + } + } } diff --git a/build.gradle b/build.gradle index 46aec8c..a770e4d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,23 @@ +apply from: "jacoco.gradle" + buildscript { - ext.kotlinVersion = '1.3.11' - ext.jacocoVersion = '0.8.1' + + ext.kotlinVersion = '1.5.21' + ext.gradlePluginVersion = '4.2.0' +// ext.gradlePluginVersion = '7.0.0' + ext.testXVersion = '1.3.0' + ext.espressoCoreVersion = '3.3.0' + ext.robolectricVersion = '4.6.1' + ext.junitVersion = '4.13' + ext.testXJunitVersion = '1.1.2' + ext.appCompatVersion = '1.2.0' repositories { google() - jcenter() + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:3.3.0-rc02' - classpath "org.jacoco:org.jacoco.core:$jacocoVersion" + classpath "com.android.tools.build:gradle:$gradlePluginVersion" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" } } @@ -16,7 +25,7 @@ buildscript { allprojects { repositories { google() - jcenter() + mavenCentral() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0731ecf..323b258 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip diff --git a/jacoco.gradle b/jacoco.gradle index c179b48..415118e 100644 --- a/jacoco.gradle +++ b/jacoco.gradle @@ -1,18 +1,16 @@ -apply plugin: 'jacoco' +apply from: "jacocoDeps.gradle" -jacoco { - toolVersion = "$jacocoVersion" -} - -tasks.withType(Test) { - jacoco.includeNoLocationClasses = true -} - -task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'createDebugCoverageReport']) { +task jacocoTestReport(type: JacocoReport) { group "Reporting" description "Generate Jacoco coverage reports." + // Make this root task depend on the unit tests of all modules + rootProject.subprojects.each { + dependsOn("${it.name}:testDebugUnitTest") + dependsOn("${it.name}:createDebugCoverageReport") + } + reports { xml.enabled = true html.enabled = true @@ -28,13 +26,18 @@ task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'crea def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*'] rootProject.subprojects.each { proj -> - javaClasses << fileTree(dir: "$proj.buildDir/intermediates/javac/debug", excludes: fileFilter) + 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, + javaSrc << "$proj.projectDir/src/main/java" + kotlinSrc << "$proj.projectDir/src/main/kotlin" + execution << fileTree(dir: proj.buildDir, includes: ['jacoco/testDebugUnitTest.exec', + // Output for AGP 7.0.0 + // 'outputs/unit_test_code_coverage/**/*.exec', 'outputs/code_coverage/debugAndroidTest/connected/**/*.ec']) + // To work around proper coverage file being empty in AGP 4.2.0 + // Rely on erroneously created root-level as well since it actually includes coverage info + execution << fileTree(dir: proj.projectDir, includes: ['jacoco.exec']) } sourceDirectories = files([javaSrc, kotlinSrc]) diff --git a/jacocoDeps.gradle b/jacocoDeps.gradle new file mode 100644 index 0000000..7ae7419 --- /dev/null +++ b/jacocoDeps.gradle @@ -0,0 +1,6 @@ +apply plugin: 'jacoco' + +tasks.withType(Test) { + jacoco.includeNoLocationClasses = true + jacoco.excludes = ['jdk.internal.*'] +} \ No newline at end of file