I have an Android app with 4 variants, and I have a Bitrise instance that runs this command:
./gradlew "testDevADebugUnitTestCoverage" "testDevBDebugUnitTest" "testDevCDebugUnitTest" "testDevCDebugUnitTest" "--continue" "-PjacocoEnabled=true"
in the develop branch to make sure everything's all right.
I have recently upgraded to Gradle 8 and AGP 8.0.1 using the AGP Upgrade Assistant from Android Studio, and I'm running into the several errors just like the one below when I'm running the command above either locally or in Bitrise.
I have to say that the Gradle errors are for a lot of different types of tasks: KotlinCompile
, JacocoReport
, MergeSourceSetFolders
, ProcessTestManifest
.
Some problems were found with the configuration of task ':domain:compileDevADebugKotlin' (type 'KotlinCompile').
- Gradle detected a problem with the following location: '/Users/MyUser/Developer/yapp/domain/build/tmp/kotlin-classes/devADebug'.
Reason: Task ':domain:testDevBDebugUnitTestCoverage' uses this output of task ':domain:compileDevADebugKotlin' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.
Possible solutions:
1. Declare task ':domain:compileDevADebugKotlin' as an input of ':domain:testDevBDebugUnitTestCoverage'.
2. Declare an explicit dependency on ':domain:compileDevADebugKotlin' from ':domain:testDevBDebugUnitTestCoverage' using Task#dependsOn.
3. Declare an explicit dependency on ':domain:compileDevADebugKotlin' from ':domain:testDevBDebugUnitTestCoverage' using Task#mustRunAfter.
Please refer to https://docs.gradle.org/8.0.2/userguide/validation_problems.html#implicit_dependency for more details about this problem.
I have tried to update Jacoco to the latest version (0.8.10) but the problem still remains (I'm not even sure it's a Jacoco problem though).
How can I resolve this issue? I have been looking around and I haven't been able to find any solution.
Edit
Here's my jacoco.gradle
file:
apply plugin: 'jacoco'
apply from: "$project.rootDir/test_coverage_excludes.gradle"
jacoco {
toolVersion = libs.versions.jacocoVersion.get()
reportsDir = file("$buildDir/reports/jacoco")
}
android {
testOptions {
unitTests.all {
jacoco {
// Required for tests ran with RobolectricTestRunner to be included in coverage
includeNoLocationClasses = true
// Required for execution using Java 11
excludes = ['jdk.internal.*']
}
}
}
}
project.afterEvaluate {
def variants
if (android.hasProperty('applicationVariants')) {
variants = android.applicationVariants.collect { it.name }
} else {
variants = android.libraryVariants.collect { it.name }
}
variants = variants.findAll { it.endsWith("Debug") || it.endsWith("debug") }
// Generate a coverage report for each variant
variants.each { variantName ->
def unitTestTaskName = "test${variantName.capitalize()}UnitTest"
def coverageTaskName = "${unitTestTaskName}Coverage"
// Create the coverage tasks
task(coverageTaskName, type: JacocoReport, dependsOn: "$unitTestTaskName") {
group = "Reporting"
description "Generate coverage reports for ${variantName.capitalize()}."
// Location of Kotlin classes
def kotlinClassDirectory = "$buildDir/tmp/kotlin-classes/$variantName"
def kotlinClassTree = fileTree(dir: kotlinClassDirectory, excludes: fileFilter)
getClassDirectories().setFrom(files([kotlinClassTree]))
// Location of the actual source
def coverageSourceDirs = [
"src/main/java",
"src/$variantName/java"
]
getAdditionalSourceDirs().setFrom(coverageSourceDirs)
getSourceDirectories().setFrom(coverageSourceDirs)
// Include both unit test and instrumentation test execution data
executionData.setFrom(fileTree(dir: buildDir, includes: ['**/*.exec', '**/*.ec']))
reports {
xml.getRequired().set(true)
html.getRequired().set(true)
csv.getRequired().set(false)
}
}
}
}