@@ -20,6 +20,13 @@ android {
2020 testInstrumentationRunner " androidx.test.runner.AndroidJUnitRunner"
2121 }
2222 lintOptions { abortOnError = false }
23+ buildTypes {
24+ debug {
25+ testCoverageEnabled true // For robolectric unit tests.
26+ enableUnitTestCoverage true // For tests that run on an emulator.
27+ }
28+ }
29+
2330 publishing {
2431 singleVariant(' release' ) {
2532 withSourcesJar()
@@ -133,3 +140,31 @@ afterEvaluate {
133140 components. release. withVariantsFromConfiguration(configurations. releaseTestFixturesVariantReleaseApiPublication) { skip() }
134141 components. release. withVariantsFromConfiguration(configurations. releaseTestFixturesVariantReleaseRuntimePublication) { skip() }
135142}
143+
144+ tasks. withType(Test ) {
145+ // Robolectric modifies classes in memory at runtime, so they lack a java.security.CodeSource
146+ // URL to their on-disk location. By default, JaCoCo ignores classes without this property.
147+ // Overriding this allows Robolectric tests to be instrumented.
148+ jacoco. includeNoLocationClasses = true
149+ // Don't instrument certain JDK internals protected from modification by JEP 403's "strong
150+ // encapsulation." Avoids IllegalAccessError, InvalidClassException and similar at runtime.
151+ jacoco. excludes = [" jdk.internal.**" ]
152+ }
153+
154+ // Android projects don't automatically get a coverage report task. We must
155+ // register one manually here and wire it up to AGP's test tasks.
156+ tasks. register(" jacocoTestReport" , JacocoReport ) {
157+ dependsOn " testDebugUnitTest"
158+
159+ reports {
160+ // For codecov.io and coveralls.
161+ xml. required = true
162+ // Use the same output location as the other subprojects.
163+ html. outputLocation = layout. buildDirectory. dir(" reports/jacoco/test/html" )
164+ }
165+
166+ sourceDirectories. from = android. sourceSets. main. java. srcDirs
167+ classDirectories. from = fileTree(dir : layout. buildDirectory. dir(" intermediates/javac/debug/classes" ),
168+ excludes : [' **/R.class' , ' **/R$*.class' , ' **/BuildConfig.class' , ' **/Manifest*.*' , ' **/*Test*.*' , ' android/**/*.*' ])
169+ executionData. from = tasks. named(" testDebugUnitTest" ). map { it. jacoco. destinationFile }
170+ }
0 commit comments