A Gradle plugin to simplify test aggregations across multiple modules and its variants: JVM test suites, Android Variants or Kotlin Multiplatform's Targets
Note
Disclaimer: since version 3.x, this plugin no longer relies on
JaCoCo Report Aggregation Plugin
neither
on Test Report Aggregation Plugin
due technical limitations of the Gradle API.
See migration guide for more details.
Apply the plugin on all the projects that needs to be aggregated and/or at the root one:
plugins {
id("io.github.gmazzo.test.aggregation") version "<latest>"
}Then use the aggregatedTestsReport to generate the reports (at its default locations):
-
build/reports/aggregated-test-resultsfor test results The task:jacocoAggregatedReportis added to the root project when applying this plugin and it can be run to produce the report. All dependenttesttasks will be run too to produce the required execution data.
The plugin will automatically detect and aggregate:
- For
javaprojects:- Any
JvmTestSuitewill be automatically aggregated - For coverage:
- The
jacocoplugin is required - Because API limitations, only the default
testjvm suite will be automatically computed - You can register further jvm suites through the
io.github.gmazzo.test.aggregation.TestAggregationCoverageReport.addTestSuiteAPI
- The
- Any
- For
com.android.application,com.android.libraryandcom.android.library.multiplatformprojects:- Any
Variantwhich itsBuilTypehasenableUnitTestCoverage = trueand/orenableAndroidTestCoverage = trueconfigured - Any
Variantwith eitherHostTestorDeviceTesttest components. (forDeviceTests, their test will only be aggregated if its testTaskis run)
- Any
- For
org.jetbrains.kotlin.multiplatformprojects:- Any
KotlinTargetthat with tests. Coverage is only supported for JVM-based ones.
- Any
Besides the variants of a single module, you can also aggregate test results and coverage from other modules of the build in a single root report.
For this, you can use the aggregateTestsFrom configuration to declare a dependency to the modules
to be aggregated:
dependencies {
aggregateTestsFrom(project(":foo"))
aggregateTestsFrom(project(":bar"))
}[^IMPORTANT] Keep in mind that every referenced module must also apply the plugin, the report will fail otherwise.
You can use the DSL to include/exclude .class files from the aggregated JaCoCo coverage
report:
reporting.reports.withType<TestAggregationCoverageReport>().configureEach {
content {
include("com/**/Login*") // will only include classes starting with `com.` containing `Login` on its name
exclude("**/*ToBeExcluded*") // will exclude classes with its name ending in `ToBeExcluded`
}
}It's important to realize the filtering is done at .class file level (compiled classes). You
should not use classes names here but GLOB patterns.
This following a is a basic and quick configuration for generating an aggregated report for all modules of the build, at the root project add:
plugins {
id("io.github.gmazzo.test.aggregation")
}
dependencies {
allprojects {
aggregateTestsFrom(project)
}
}Then run:
./gradlew aggregateTestsFromBy default, the plugin will configure independent report entries for each detected variant.
In case you want to unify the results of multiple variants into a single report entry, you can use the
supersededBy DSL to declare which variant will be the one to collect the data from the others.
For instance, the following configuration will unify all variants into a single report entry called single:
aggregatedTestCoverage.variants {
val single = create("single")
all {
if (this != single) { supersededBy(single) }
}
}By default, any detected variant (JVM test suites, Android Variant or Kotlin Target) will be aggregated.
However, you can filter which variants are aggregated by using the aggregateTests API:
For Java:
testing.suites.create<JvmTestSuite>("integrationTest") {
aggregateTests = false // this suite will not be aggregated
}For Android:
androidComponents {
onVariants { variant ->
variant.aggregateTests = false
}
}Note
Due to some technical limitations in AGP, the aggregateTests DSL for Android variants in Groovy DSL must be delegated to its compileConfiguration configuration:
androidComponents {
onVariants { variant ->
variant.compileConfiguration.aggregateTests.set(true)
}
}For Kotlin Multiplatform:
kotlin {
android {
aggregateTests = false
}
jvm()
js {
aggregateTests = false
}
}Device tests aggregation can be optionally enabled through the DSL.
To consume the results of connected devices, set:
testOptions {
aggregateConnectedDevices = true
}Caution
With this set, the build will fail if no connected devices are available.
Also, Managed Devices are supported,
on both the Unified Test Platform and AGP's built-in test platform
(android.experimental.androidTest.builtin_test_platform=true).
You can aggregate them with aggregateTests DSL:
android {
testOptions {
managedDevices.localDevices.all {
aggregateTests = true
}
}
}