// Copyright 2021 the original author or authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

[[jacoco_report_aggregation_plugin]]
= The JaCoCo Report Aggregation Plugin

The JaCoCo Report Aggregation plugin (plugin id: `jacoco-report-aggregation`) provides the ability to aggregate the results of multiple JaCoCo code coverage reports (potentially spanning multiple Gradle projects) into a single HTML report.  The binary data backing the coverage reports are produced by link:{groovyDslPath}/org.gradle.api.tasks.testing.Test.html[Test] task invocations; see more at the <<jacoco_plugin#jacoco_plugin,JaCoCo Plugin>> chapter.

[[sec:jacoco_report_aggregation_usage]]
== Usage

To use the JaCoCo Report Aggregation plugin, include the following in your build script:

[.multi-language-text.lang-groovy]
----
plugins {
    id 'jacoco-report-aggregation'
}
----
[.multi-language-text.lang-kotlin]
----
plugins {
    id("jacoco-report-aggregation")
}
----

Note that this plugin takes no action unless applied in concert with the <<jvm_test_suite_plugin#jvm_test_suite_plugin,JVM Test Suite Plugin>>.  The <<java_plugin#java_plugin, Java Plugin>> automatically applies the JVM Test Suite Plugin.

There are now two ways to collect code coverage results across multiple subprojects:

1. From the distribution's project, such as an application or WAR subproject -> link:../samples/sample_jvm_multi_project_with_code_coverage_distribution.html[distribution sample]
2. Using a standalone project to specify subprojects -> link:../samples/sample_jvm_multi_project_with_code_coverage_standalone.html[standalone sample]

Example 2 could also be used to aggregate results via the root project.

[WARNING]
====
The JaCoCo Report Aggregation plugin does not currently work with the ``com.android.application`` plugin.
====

[[sec:jacoco_report_aggregation_tasks]]
== Tasks

When the project also applies the `jvm-test-suite` plugin, the following tasks are added for each test suite:

`__testSuite__CodeCoverageReport` — link:{groovyDslPath}/org.gradle.testing.jacoco.tasks.JacocoReport.html[JacocoReport]::
_Depends on_: Artifacts of variants matching the below attributes
+
Collects variants of direct and transitive project dependencies via the `jacocoAggregation` configuration. The following Attributes will be matched:

[source]
----
    - org.gradle.category              = verification   // <1>
    - org.gradle.testsuite.type        = unit-test      // <2>
    - org.gradle.verificationtype      = jacoco-results   // <3>
----
<1> Category attribute; value is fixed.
<2> TestSuiteType attribute; value is derived from link:{javadocPath}/org/gradle/api/plugins/jvm/JvmTestSuite.html#getTestType--[JvmTestSuite#getTestType()].
<3> VerificationType attribute; value is fixed.

More information about the variants produced by test execution with JaCoCo are available in the <<jacoco_plugin#sec:outgoing_variants,Outgoing Variants>> section of the JaCoCo Plugin documentation.

== Reports

[IMPORTANT]
====
By default, Gradle stops executing tasks when any task fails -- including test failures. To ensure that your builds always generate aggregation reports, specify the `--continue` option in your Gradle command. For more information, see <<command_line_interface.adoc#sec:continue_build_on_failure, continuing the build when a failure occurs>>.
====

=== Automatic report creation

When the project also applies the `jvm-test-suite` plugin, the following reporting objects are added for each test suite:

`__testSuite__CodeCoverageReport` — link:{javadocPath}/org/gradle/testing/jacoco/plugins/JacocoCoverageReport.html[JacocoCoverageReport]::
Creates a container to parameterize the link:{javadocPath}/org/gradle/api/attributes/TestSuiteType.html[TestSuiteType] value.

=== Manual report creation

When the project does not apply the `jvm-test-suite` plugin, you must manually register one or more reports:

.Create a reporting container
====
include::sample[dir="samples/incubating/java/jvm-multi-project-with-code-coverage-standalone/groovy/code-coverage-report",files="build.gradle[tags=create_report]"]
include::sample[dir="samples/incubating/java/jvm-multi-project-with-code-coverage-standalone/kotlin/code-coverage-report",files="build.gradle.kts[tags=create_report]"]
====
<.> Creates a report named `testCodeCoverageReport` of type `JacocoCoverageReport`.  For convenience, sets `TestType` using a constant value from the  link:{javadocPath}/org/gradle/api/attributes/TestSuiteType.html[TestSuiteType] class.  Any String value is acceptable.

Report creation automatically creates backing tasks to aggregate coverage results for the given test suite type value.

[[sec:dependency_management]]
== Dependency management
The JaCoCo Report Aggregation plugin adds the following dependency configurations:

.JaCoCo Report Aggregation plugin - dependency configurations
[cols="a,a", options="header"]
|===
| Name
| Meaning

| `jacocoAggregation`
| The configuration used to declare all project dependencies having code coverage data to be aggregated.
| `allCodeCoverageReportSourceDirectories`
| Consumes the project dependencies from the `jacocoAggregation` configuration to collect all `main-source` variants.  Prevents external libraries' classes from being included in the aggregated results.
| `allCodeCoverageReportClassDirectories`
| Consumes the project dependencies from the `jacocoAggregation` configuration to collect all classes directories.  Prevents external libraries' classes from being included in the aggregated results.
| `__testReportName__ExecutionData`
| Consumes the project dependencies from the `jacocoAggregation` configuration using <<variant_model#sec:variant-aware-matching,variant-aware matching>> to find the appropriate test suite type.
|===

It is not necessary to explicitly add dependencies to the `jacocoAggregation` configuration if the project also applies the `jvm-test-suite` plugin.

Note the `__testReportName__ExecutionData` and `allCodeCoverageReport*Directories` configurations may display resolution errors for external dependencies, as these do not expose code coverage data.  This is expected behavior and does not affect the outcome of the build or code coverage aggregation process.
