I set up a Jacoco coverage report for our Kotlin Android project, which is supposed to run in gitlab-ci as job. I followed this article to generate the gradle tasks. The coverage report works perfectly if run locally. But if the same gradle task is executed in the gitlab runner, it always produces empty reports with the message "No class files specified".
What's different in the pipeline when it comes to class files?
Maybe one of you is able to spot the issue.
jacoco.gradle:
apply plugin: 'jacoco'
android {
testOptions {
unitTests.all {
jacoco {
includeNoLocationClasses = true
}
}
}
jacoco {
version = '0.8.4'
}
}
project.afterEvaluate {
def buildTypes = android.buildTypes.collect { type ->
type.name
}
def productFlavors = android.productFlavors.collect { flavor ->
flavor.name
}
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"
task "${testTaskName}Coverage" (type:JacocoReport, dependsOn: "$testTaskName") {
group = "Reporting"
description = "Generate Jacoco coverage reports on the ${sourceName.capitalize()} build."
classDirectories = fileTree(
dir: "$project.buildDir/tmp/kotlin-classes/${sourcePath}",
excludes: ['**/R.class'] #List of excludes is reduced for this question
)
def coverageSourceDirs = [
"$project.buildDir.parent/src/main/java",
"$project.buildDir.parent/src/$productFlavorName/java",
"$project.buildDir.parent/src/$buildTypeName/java"
]
additionalSourceDirs = files(coverageSourceDirs)
sourceDirectories = files(coverageSourceDirs)
executionData = files("${project.buildDir}/jacoco/${testTaskName}.exec")
reports {
xml.enabled = true
html.enabled = true
}
}
}
}
}
gitlab-ci.yml: (unrelated jobs and stages removed)
image: docker:latest
variables:
BUILDER_VERSION: "68e9780a"
GRADLE_ARGS_CI: "--no-daemon --stacktrace"
stages:
- build
- test
.build-template: &build_definition
stage: build
image: our-docker-registry.com/android-builder:$BUILDER_VERSION
tags:
- frontend
only:
- merge_requests
- develop
- schedules
.test-template: &test_definition
stage: test
image: our-docker-registry.com/android-builder:$BUILDER_VERSION
tags:
- hermine-frontend
only:
- merge_requests
- develop
- schedules
build:dev:debug:
<<: *build_definition
script:
- echo "Starting SCRIPT in job $CI_JOB_NAME"
- ./gradlew $GRADLE_ARGS_CI :app:assembleDevDebug
artifacts:
paths:
- app/build/outputs/apk/dev/debug
- app/build/tmp/
expire_in: 1 week
test:dev:debug:
<<: *test_definition
script:
- echo "Starting SCRIPT in job $CI_JOB_NAME"
- ./gradlew $GRADLE_ARGS_CI -Pci --console=plain :app:testDevDebugUnitTest
- ./gradlew $GRADLE_ARGS_CI -Pci --console=plain :app:testDevDebugUnitTestCoverage
artifacts:
paths:
- app/build/reports/tests/testDevDebugUnitTest
- app/build/jacoco #execution file
- app/build/reports
expire_in: 1 day
