Ankit Sharma
11/07/2024, 10:34 AMAnkit Sharma
11/07/2024, 10:35 AMpackage plugins
plugins { jacoco }
configurations.all {
resolutionStrategy {
eachDependency {
when (requested.group) {
"org.jacoco" -> useVersion(Versions.BuildPlugins.jacoco)
// ...etc
}
}
}
}
val jacocoExceptionsExtension = project.extensions.getByType(JacocoExceptionsExtension::class.java)
apply {
project.apply<DiffCoveragePlugin>()
if (isAndroidModule()) {
setupAndroidReporting()
} else {
setupKotlinReporting()
}
}
fun isAndroidLibraryModule(): Boolean {
return project.plugins.hasPlugin("com.android.library")
}
fun isAndroidModule(): Boolean {
val isAndroidLibrary = project.plugins.hasPlugin("com.android.library")
val isAndroidApp = project.plugins.hasPlugin("com.android.application")
return isAndroidLibrary || isAndroidApp
}
fun setupKotlinReporting() {
registerTasks("test")
}
fun setupAndroidReporting() {
tasks.withType<Test> {
configure<JacocoTaskExtension> {
isIncludeNoLocationClasses = true
ignoreFailures = false
excludes = listOf("jdk.internal.*")
}
}
registerTasks("testDebugUnitTest", isAndroidLibraryModule())
}
fun registerTasks(dependsOnTask: String, isAndroidLibrary: Boolean = false) {
/** Jacoco command to generate report of unit test coverage */
if (tasks.findByName("jacocoAndroidTestReport") == null) {
tasks.register<JacocoReport>("jacocoAndroidTestReport") {
enabled = true
group = "verification"
description = "Code coverage report for both Android and Unit tests."
setDirectories(jacocoExceptionsExtension.fileFilters.orNull)
dependsOn(dependsOnTask)
// this is to fix a compile issue where for libs it is asking to declare this dependency
if (isAndroidLibrary) {
dependsOn("compileDebugLibraryResources")
}
reports { reports() }
setDirectories(jacocoExceptionsExtension.fileFilters.orNull)
}
}
if (tasks.findByName("jacocoAndroidCoverageVerification") == null) {
tasks.register<JacocoCoverageVerification>("jacocoAndroidCoverageVerification") {
enabled = true
group = "verification"
description = "Code coverage verification for Android both Android and Unit tests."
dependsOn(dependsOnTask)
violationRules {
rule {
limit {
counter = "INSTRUCTIONAL"
value = "COVEREDRATIO"
minimum = "0.5".toBigDecimal()
}
}
}
setDirectories(jacocoExceptionsExtension.fileFilters.orNull)
}
}
}
fun getClassDirectoriesTree(filters: Array<String>?): FileTree {
return fileTree(project.buildDir) {
include(JacocoConstants.classDirectories)
exclude(getFileFilters(filters))
}
}
fun getFileFilters(filters: Array<String>?): List<String> {
return if (filters != null) {
getDefaultFileFilter().toMutableList().apply { addAll(filters) }
} else {
getDefaultFileFilter()
}
}
fun getDefaultFileFilter(): List<String> = JacocoConstants.fileFilter.toMutableList()
private val sourceDirectoriesTree =
fileTree("${project.buildDir}") { include(JacocoConstants.sourceDirectories) }
private val executionDataTree =
fileTree(project.buildDir) { include(JacocoConstants.executionDirectories) }
fun JacocoReportsContainer.reports() {
xml.required.set(true)
html.required.set(true)
xml.outputLocation.set(file("${buildDir}/reports/jacoco/jacocoTestReport/jacocoTestReport.xml"))
html.outputLocation.set(file("${buildDir}/reports/jacoco/jacocoTestReport/html"))
}
fun JacocoCoverageVerification.setDirectories(filters: Array<String>?) {
sourceDirectories.setFrom(sourceDirectoriesTree)
classDirectories.setFrom(getClassDirectoriesTree(filters))
executionData.setFrom(executionDataTree)
}
fun JacocoReport.setDirectories(filters: Array<String>?) {
sourceDirectories.setFrom(sourceDirectoriesTree)
classDirectories.setFrom(getClassDirectoriesTree(filters))
executionData.setFrom(executionDataTree)
}
Ankit Sharma
11/07/2024, 10:37 AMVampire
11/07/2024, 11:30 AM