<lambda>null1plugins { 2 alias(libs.plugins.jacoco) 3 alias(libs.plugins.robolectric.java.module) 4 } 5 6 val jacocoVersion = libs.versions.jacoco.get() 7 val jacocoAnt: Configuration by configurations.getting 8 val jacocoRuntime: Configuration by configurations.creating 9 <lambda>null10jacoco { toolVersion = jacocoVersion } 11 <lambda>null12dependencies { 13 testCompileOnly(AndroidSdk.MAX_SDK.coordinates) 14 testRuntimeOnly(AndroidSdk.MAX_SDK.coordinates) 15 16 testImplementation(project(":robolectric")) 17 testImplementation(libs.junit4) 18 testImplementation("org.jacoco:org.jacoco.agent:$jacocoVersion:runtime") 19 } 20 21 val unitTestTaskName = "test" 22 val javaDir = layout.buildDirectory.dir("classes/java/main").get().asFile 23 val kotlinDir = layout.buildDirectory.dir("classes/kotlin/main").get().asFile 24 val jacocoInstrumentedClassesOutputDir = 25 layout.buildDirectory.dir("$jacocoVersion/classes/java/classes-instrumented").get().asFile 26 27 // Make sure it's evaluated after the AGP evaluation. <lambda>null28afterEvaluate { 29 tasks.classes.configure { 30 doLast { 31 logger.debug("[JaCoCo] Generating JaCoCo instrumented classes for the build.") 32 33 if (jacocoInstrumentedClassesOutputDir.exists()) { 34 logger.debug("[JaCoCo] Classes had been instrumented.") 35 return@doLast 36 } 37 38 ant.withGroovyBuilder { 39 "taskdef"( 40 "name" to "instrument", 41 "classname" to "org.jacoco.ant.InstrumentTask", 42 "classpath" to jacocoAnt.asPath, 43 ) 44 } 45 46 if (javaDir.exists()) { 47 ant.withGroovyBuilder { 48 "instrument"("destdir" to jacocoInstrumentedClassesOutputDir.path) { 49 "fileset"("dir" to javaDir.path, "excludes" to "") 50 } 51 } 52 } else { 53 logger.debug("[JaCoCo] Classes directory with path '{}' does not exist.", javaDir) 54 } 55 56 if (kotlinDir.exists()) { 57 ant.withGroovyBuilder { 58 "instrument"("destdir" to jacocoInstrumentedClassesOutputDir.path) { 59 "fileset"("dir" to kotlinDir.path, "excludes" to "") 60 } 61 } 62 } else { 63 logger.debug("[JaCoCo] Classes directory with path '{}' does not exist.", kotlinDir) 64 } 65 } 66 } 67 68 val executionDataFilePath = 69 layout.buildDirectory.dir("jacoco").get().file("${unitTestTaskName}.exec").asFile.path 70 71 // Put JaCoCo instrumented classes and JaCoCoRuntime at the beginning of the JVM classpath. 72 tasks.named<Test>(unitTestTaskName).configure { 73 doFirst { 74 // Disable JaCoCo on-the-fly from Gradle JaCoCo plugin. 75 extensions.configure<JacocoTaskExtension> { isEnabled = false } 76 77 logger.debug("[JaCoCo] Modifying classpath of tests JVM.") 78 79 systemProperty("jacoco-agent.destfile", executionDataFilePath) 80 81 classpath = files(jacocoInstrumentedClassesOutputDir.path) + classpath + jacocoRuntime 82 83 logger.debug("[JaCoCo] Final test JVM classpath is ${classpath.asPath}") 84 } 85 } 86 } 87